Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Protected Attributes
nsMacEventHandler Class Reference

#include <nsMacEventHandler.h>

Collaboration diagram for nsMacEventHandler:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsMacEventHandler (nsMacWindow *aTopLevelWidget, nsMacEventDispatchHandler *aEventDispatchHandler)
virtual ~nsMacEventHandler ()
virtual PRBool HandleOSEvent (EventRecord &aOSEvent)
virtual PRBool DragEvent (unsigned int aMessage, Point aMouseGlobal, UInt16 aKeyModifiers)
virtual long HandlePositionToOffset (Point aPoint, short *regionClass)
virtual nsresult HandleOffsetToPosition (long offset, Point *position)
virtual nsresult UnicodeHandleUpdateInputArea (const PRUnichar *text, long charCount, long fixedLength, TextRangeArray *textRangeArray)
virtual nsresult HandleUnicodeGetSelectedText (nsAString &outString)
virtual nsresult ResetInputState ()
virtual PRBool HandleUKeyEvent (const PRUnichar *text, long charCount, EventRecord &aOSEvent)
virtual PRBool HandleKeyUpDownEvent (EventHandlerCallRef aHandlerCallRef, EventRef aEvent)
virtual PRBool HandleKeyModifierEvent (EventHandlerCallRef aHandlerCallRef, EventRef aEvent)
virtual PRBool ResizeEvent (WindowRef inWindow)
virtual PRBool Scroll (PRInt32 aDeltaY, PRInt32 aDeltaX, PRBool aIsPixels, const Point &aMouseLoc, nsWindow *aWindow, PRUint32 aModifiers)
virtual void HandleActivateEvent (EventRef aEvent)
nsMacEventDispatchHandlerGetEventDispatchHandler ()
void ClearWindowRefs (nsWindow *aWindow)

Protected Member Functions

void InitializeMouseEvent (nsMouseEvent &aMouseEvent, nsPoint &aPoint, PRInt16 aModifiers, PRUint32 aClickCount)
void InitializeKeyEvent (nsKeyEvent &aKeyEvent, EventRecord &aOSEvent, nsWindow *aFocusedWidget, PRUint32 aMessage, PRBool aConvertChar=PR_TRUE)
virtual PRBool IsSpecialRaptorKey (UInt32 macKeyCode)
virtual PRUint32 ConvertKeyEventToUnicode (EventRecord &aOSEvent)
virtual PRBool HandleMouseDownEvent (EventRecord &aOSEvent)
virtual PRBool HandleMouseUpEvent (EventRecord &aOSEvent)
virtual PRBool HandleMouseMoveEvent (EventRecord &aOSEvent)
virtual void ConvertOSEventToMouseEvent (EventRecord &aOSEvent, nsMouseEvent &aMouseEvent, PRUint32 aMessage)
virtual nsresult HandleStartComposition (void)
virtual nsresult HandleEndComposition (void)
virtual nsresult HandleTextEvent (PRUint32 textRangeCount, nsTextRangeArray textRangeArray)
virtual PRBool ScrollAxis (nsMouseScrollEvent::nsMouseScrollFlags aAxis, PRInt32 aDelta, PRBool aIsPixels, const Point &aMouseLoc, nsWindow *aWindow, PRUint32 aModifiers)
void ClearLastMouseUp ()
PRBool IsPluginFocused ()

Protected Attributes

nsMacEventDispatchHandlermEventDispatchHandler
nsMacWindowmTopLevelWidget
RgnHandle mUpdateRgn
TSMDocumentID mTSMDocument
nsPoint mIMEPos
nsAutoStringmIMECompositionStr
Point mLastMouseUpWhere
UInt32 mLastMouseUpWhen
PRUint32 mClickCount
PRUint32 mLastModifierState
PRPackedBool mIMEIsComposing
PRPackedBool mKeyIgnore
PRPackedBool mKeyHandled
PRPackedBool mMouseInWidgetHit
PRPackedBool mOwnEventDispatchHandler

Detailed Description

Definition at line 102 of file nsMacEventHandler.h.


Constructor & Destructor Documentation

nsMacEventHandler::nsMacEventHandler ( nsMacWindow aTopLevelWidget,
nsMacEventDispatchHandler aEventDispatchHandler 
)

Definition at line 334 of file nsMacEventHandler.cpp.

{
  OSErr err;
  InterfaceTypeList supportedServices;

  mTopLevelWidget = aTopLevelWidget;

  //
  // create a TSMDocument for this window.  We are allocating a TSM document for
  // each Mac window
  //
  mTSMDocument = nsnull;
  supportedServices[0] = kUnicodeDocument;
  err = ::NewTSMDocument(1, supportedServices,&mTSMDocument, (long)this);
  NS_ASSERTION(err==noErr, "nsMacEventHandler::nsMacEventHandler: NewTSMDocument failed.");
#ifdef DEBUG_TSM
  printf("nsMacEventHandler::nsMacEventHandler: created TSMDocument[%p]\n", mTSMDocument);
#endif

  // make sure we do not use input widnow even some other code turn it for default by calling 
  // ::UseInputWindow(nsnull, TRUE); 
  if (mTSMDocument)
    ::UseInputWindow(mTSMDocument, FALSE); 
         
  mIMEIsComposing = PR_FALSE;
  mIMECompositionStr = nsnull;

  mKeyIgnore = PR_FALSE;
  mKeyHandled = PR_FALSE;

  mLastModifierState = 0;

  mMouseInWidgetHit = PR_FALSE;

  ClearLastMouseUp();

  if (aEventDispatchHandler) {
    mEventDispatchHandler = aEventDispatchHandler;
    mOwnEventDispatchHandler = PR_FALSE;
  }
  else {
    mEventDispatchHandler = new nsMacEventDispatchHandler();
    mOwnEventDispatchHandler = PR_TRUE;
  }
}

Here is the call graph for this function:

Definition at line 382 of file nsMacEventHandler.cpp.

{
       if (mTSMDocument)
              (void)::DeleteTSMDocument(mTSMDocument);
       if(nsnull != mIMECompositionStr) {
              delete mIMECompositionStr;
              mIMECompositionStr = nsnull;
       }

       if (mOwnEventDispatchHandler)
              delete mEventDispatchHandler;

  if (sLastActive == this) {
    // This shouldn't happen
    sLastActive = nsnull;
  }
}

Member Function Documentation

Definition at line 2479 of file nsMacEventHandler.cpp.

Here is the caller graph for this function:

Definition at line 2512 of file nsMacEventHandler.cpp.

{
  if (sLastActive && sLastActive->mTopLevelWidget == aWindow) {
    sLastActive = nsnull;
  }
}
PRUint32 nsMacEventHandler::ConvertKeyEventToUnicode ( EventRecord &  aOSEvent) [protected, virtual]

Definition at line 983 of file nsMacEventHandler.cpp.

{
       char charResult = aOSEvent.message & charCodeMask;
       
       //
       // get the script of text for Unicode conversion
       //
       ScriptCode textScript = (ScriptCode)GetScriptManagerVariable(smKeyScript);

       //
       // convert our script code (smKeyScript) to a TextEncoding 
       //
       TextEncoding textEncodingFromScript;
       OSErr err = ::UpgradeScriptInfoToTextEncoding(textScript, kTextLanguageDontCare, kTextRegionDontCare, nsnull,
                                                                             &textEncodingFromScript);
       NS_ASSERTION(err == noErr, "nsMacEventHandler::ConvertKeyEventToUnicode: UpgradeScriptInfoToTextEncoding failed.");
       if (err != noErr) return 0;
       
       TextToUnicodeInfo    textToUnicodeInfo;
       err = ::CreateTextToUnicodeInfoByEncoding(textEncodingFromScript,&textToUnicodeInfo);
       NS_ASSERTION(err == noErr, "nsMacEventHandler::ConvertKeyEventToUnicode: CreateUnicodeToTextInfoByEncoding failed.");
       if (err != noErr) return 0;

       //
       // convert to Unicode
       //
       ByteCount result_size, source_read;
       PRUnichar unicharResult[UNICODE_BUFFER_SIZE_FOR_KEY];
       err = ::ConvertFromTextToUnicode(textToUnicodeInfo,
                                                               sizeof(char),&charResult,
                                                               kUnicodeLooseMappingsMask,
                                                               0,NULL,NULL,NULL,
                                                               sizeof(PRUnichar)*UNICODE_BUFFER_SIZE_FOR_KEY,&source_read,
                                                               &result_size,NS_REINTERPRET_CAST(PRUint16*, unicharResult));
       ::DisposeTextToUnicodeInfo(&textToUnicodeInfo);
       NS_ASSERTION(err == noErr, "nsMacEventHandler::ConvertKeyEventToUnicode: ConverFromTextToUnicode failed.");
       // if we got the following result, then it mean we got more than one Unichar from it.
       NS_ASSERTION(result_size == 2, "nsMacEventHandler::ConvertKeyEventToUnicode: ConverFromTextToUnicode failed.");
       // Fix Me!!!
       // the result_size will not equal to 2 in the following cases:
       //
       // 1. Hebrew/Arabic scripts, when we convert ( ) { } [ ]  < >  etc. 
       // The TEC will produce result_size = 6 (3 PRUnichar*) :
       // one Right-To-Left-Mark, the char and one Left-To-Right-Mark
       // We should fix this later...
       // See the following URL for the details...
       // ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/APPLE/ARABIC.TXT
       // ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/APPLE/FARSI.TXT
       // ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/APPLE/HEBREW.TXT
       //
       // 2. Also, it probably won't work in Thai and Indic keyboard since one char may convert to
       // several PRUnichar. It sometimes add zwj or zwnj. See the following url for details.
       // ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/APPLE/DEVANAGA.TXT
       // ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/APPLE/GUJARATI.TXT
       // ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/APPLE/GURMUKHI.TXT
       // ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/APPLE/THAI.TXT
       
//     if (err != noErr) return 0;
// I think we should ignore the above error since we already have the result we want

       return unicharResult[0];
}

Here is the caller graph for this function:

void nsMacEventHandler::ConvertOSEventToMouseEvent ( EventRecord &  aOSEvent,
nsMouseEvent aMouseEvent,
PRUint32  aMessage 
) [protected, virtual]

Definition at line 1733 of file nsMacEventHandler.cpp.

{
       // we're going to time double-clicks from mouse *up* to next mouse *down*
       if (aMessage == NS_MOUSE_LEFT_BUTTON_UP  ||
      aMessage == NS_MOUSE_RIGHT_BUTTON_UP ||
      aMessage == NS_MOUSE_MIDDLE_BUTTON_UP)
       {
              // remember when this happened for the next mouse down
              mLastMouseUpWhen = aOSEvent.when;
              mLastMouseUpWhere = aOSEvent.where;
       }
       else if (aMessage == NS_MOUSE_LEFT_BUTTON_DOWN  ||
           aMessage == NS_MOUSE_RIGHT_BUTTON_DOWN ||
           aMessage == NS_MOUSE_MIDDLE_BUTTON_DOWN)
       {
              // now look to see if we want to convert this to a double- or triple-click
              const short kDoubleClickMoveThreshold     = 5;
              
              if (((aOSEvent.when - mLastMouseUpWhen) < ::GetDblTime()) &&
                            (((abs(aOSEvent.where.h - mLastMouseUpWhere.h) < kDoubleClickMoveThreshold) &&
                                   (abs(aOSEvent.where.v - mLastMouseUpWhere.v) < kDoubleClickMoveThreshold))))
              {             
                     mClickCount ++;
                     
//                   if (mClickCount == 2)
//                          aMessage = NS_MOUSE_LEFT_DOUBLECLICK;
              }
              else
              {
                     // reset the click count, to count *this* click
                     mClickCount = 1;
              }
       }

       // get the widget hit and the hit point inside that widget
       nsWindowType wtype;
       mTopLevelWidget->GetWindowType(wtype);
       PRBool          topLevelIsAPopup = (wtype == eWindowType_popup);
       WindowRef       eventTargetWindow = reinterpret_cast<WindowRef>(mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY));

       WindowPtr       windowThatHasEvent = nsnull;
       ControlPartCode partCode = ::FindWindow(aOSEvent.where, &windowThatHasEvent);

       // if the mouse button is still down, send events to the last widget hit unless the
       // new event is in a popup window.
       nsWindow* lastWidgetHit = mEventDispatchHandler->GetWidgetHit();
       nsWindow* widgetHit = nsnull;
       if (lastWidgetHit)
       {
        // make sure we in the same window as where we started before we go assuming
        // that we know where the event will go.
        WindowRef   lastWind = reinterpret_cast<WindowRef>(lastWidgetHit->GetNativeData(NS_NATIVE_DISPLAY));
        PRBool      eventInSameWindowAsLastEvent = (windowThatHasEvent == lastWind);
        if ( eventInSameWindowAsLastEvent || !topLevelIsAPopup ) {      
            if (::StillDown() || aMessage == NS_MOUSE_LEFT_BUTTON_UP)
            {
                widgetHit = lastWidgetHit;
                eventTargetWindow = lastWind;   // make sure we use the correct window to fix the coords
            }
            else
            {
                // Some widgets can eat mouseUp events (text widgets in TEClick, sbars in TrackControl).
                // In that case, stop considering this widget as being still hit.
                mEventDispatchHandler->SetWidgetHit(nsnull);
            }
        }
       }

       Point hitPoint = aOSEvent.where;
       nsGraphicsUtils::SafeSetPortWindowPort(eventTargetWindow);

       {
           StOriginSetter  originSetter(eventTargetWindow);
       ::GlobalToLocal(&hitPoint);     // gives the mouse loc in local coords of the hit window
       }
       
       nsPoint widgetHitPoint(hitPoint.h, hitPoint.v);

       // if the mouse is in the grow box, pretend that it has left the window
       if ( partCode != inGrow ) {
              if (! widgetHit)
                     widgetHit = mTopLevelWidget->FindWidgetHit(hitPoint);
       
              if (widgetHit)
              {
                     nsRect bounds;
                     widgetHit->GetBounds(bounds);
                     nsPoint widgetOrigin(bounds.x, bounds.y);
                     widgetHit->LocalToWindowCoordinate(widgetOrigin);
                     widgetHitPoint.MoveBy(-widgetOrigin.x, -widgetOrigin.y);
              }
       }

    // if we haven't found anything and we're tracking the mouse for a popup, then
    // it's probable that the coordinates are just negative and we were dispatched
    // here just cuz we're the top window in the app right now. In that case, just
    // set the widget hit to this one. It's harmless (I hope), and it avoids asserts
    // in the view code about null widgets.
    if ( !widgetHit && topLevelIsAPopup && (hitPoint.h < 0 || hitPoint.v < 0) )
        widgetHit = mTopLevelWidget;

    InitializeMouseEvent(aMouseEvent, widgetHitPoint, aOSEvent.modifiers,
                         mClickCount);

    // nsEvent
    aMouseEvent.message     = aMessage;

    // nsGUIEvent
    aMouseEvent.widget      = widgetHit;
    aMouseEvent.nativeMsg   = (void*)&aOSEvent;

    // nsMouseEvent
    aMouseEvent.acceptActivation = PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsMacEventHandler::DragEvent ( unsigned int  aMessage,
Point  aMouseGlobal,
UInt16  aKeyModifiers 
) [virtual]

Definition at line 535 of file nsMacEventHandler.cpp.

{
  // Convert the mouse to local coordinates.  We have to do all the funny port
  // origin stuff just in case it has been changed.
  Point hitPointLocal = aMouseGlobal;
  WindowRef wind =
   NS_STATIC_CAST(WindowRef, mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY));
  nsGraphicsUtils::SafeSetPortWindowPort(wind);
  {
    StOriginSetter  originSetter(wind);
    ::GlobalToLocal(&hitPointLocal);
  }
  nsPoint widgetHitPoint(hitPointLocal.h, hitPointLocal.v);

  nsWindow* widgetHit = mTopLevelWidget->FindWidgetHit(hitPointLocal);
  if (widgetHit) {
    // Adjust from local coordinates to window coordinates in case the hit
    // widget isn't at (0, 0).
    nsRect bounds;
    widgetHit->GetBounds(bounds);
    nsPoint widgetOrigin(bounds.x, bounds.y);
    widgetHit->LocalToWindowCoordinate(widgetOrigin);
    widgetHitPoint.MoveBy(-widgetOrigin.x, -widgetOrigin.y);          
  }

  // Note that aMessage will be NS_DRAGDROP_(ENTER|EXIT|OVER|DROP) depending
  // on the state of the drag relative to the top-level window, not the
  // widget that interests us.  As a result, NS_DRAGDROP_ENTER and
  // NS_DRAGDROP_EXIT events must be synthesized as the drag moves between
  // widgets in this window.

  if (aMessage == NS_DRAGDROP_EXIT) {
    // If the drag is leaving the window, it can't be over a widget contained
    // within the window.
    widgetHit = nsnull;
  }

  nsWindow* lastWidget = mEventDispatchHandler->GetWidgetPointed();
  if (lastWidget != widgetHit) {
    if (aMessage != NS_DRAGDROP_ENTER) {
      if (lastWidget) {
        // Send an NS_DRAGDROP_EXIT event to the last widget.  This is not done
        // if aMessage == NS_DRAGDROP_ENTER, because that indicates that the
        // drag is either beginning (in which case there is no valid last
        // widget for the drag) or reentering the window (in which case
        // NS_DRAGDROP_EXIT was sent when the mouse left the window).

        nsMouseEvent exitEvent(PR_TRUE, NS_DRAGDROP_EXIT, lastWidget,
                               nsMouseEvent::eReal);
        nsPoint zero(0, 0);
        InitializeMouseEvent(exitEvent, zero, aKeyModifiers, 1);
        lastWidget->DispatchMouseEvent(exitEvent);
      }

      if (aMessage != NS_DRAGDROP_EXIT && widgetHit) {
        // Send an NS_DRAGDROP_ENTER event to the new widget.  This is not
        // done when aMessage == NS_DRAGDROP_EXIT, because that indicates
        // that the drag is leaving the window.

        nsMouseEvent enterEvent(PR_TRUE, NS_DRAGDROP_ENTER, widgetHit,
                                nsMouseEvent::eReal);
        InitializeMouseEvent(enterEvent, widgetHitPoint, aKeyModifiers, 1);
        widgetHit->DispatchMouseEvent(enterEvent);
      }
    }
  }

  // update the tracking of which widget the mouse is now over.
  mEventDispatchHandler->SetWidgetPointed(widgetHit);

  if (!widgetHit) {
    // There is no widget to receive the event.  This happens when the drag
    // leaves the window or when the drag moves over a part of the window
    // not containing any widget, such as the title bar.  When appropriate,
    // NS_DRAGDROP_EXIT was dispatched to lastWidget above, so there's nothing
    // to do but return.
    return PR_TRUE;
  }

  nsMouseEvent geckoEvent(PR_TRUE, aMessage, widgetHit, nsMouseEvent::eReal);
  InitializeMouseEvent(geckoEvent, widgetHitPoint, aKeyModifiers, 1);
  widgetHit->DispatchMouseEvent(geckoEvent);

  return PR_TRUE;
}

Here is the call graph for this function:

Definition at line 143 of file nsMacEventHandler.h.

void nsMacEventHandler::HandleActivateEvent ( EventRef  aEvent) [virtual]

Definition at line 1168 of file nsMacEventHandler.cpp.

{
  ClearLastMouseUp();

  OSErr err;
  PRUint32 eventKind = ::GetEventKind(aEvent);
  PRBool isActive = (eventKind == kEventWindowActivated) ? PR_TRUE : PR_FALSE;

  // Be paranoid about deactivating the last-active window before activating
  // the new one, and about not handling activation for the already-active
  // window.

       if (isActive && sLastActive != this)
       {
              if (sLastActive) {
                     WindowRef oldWindow = NS_STATIC_CAST(WindowRef,
                      sLastActive->mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY));
                     // Deactivating also causes HandleActivateEvent to
                     // be called on sLastActive with isActive = PR_FALSE,
                     // so sLastActive will be nsnull after this call.
                     ::ActivateWindow(oldWindow, PR_FALSE);
              }

              sLastActive = this;

              //
              // Activate The TSMDocument associated with this handler
              //
              if (mTSMDocument) {
                // make sure we do not use input widnow even some other code turn it for default by calling 
                // ::UseInputWindow(nsnull, TRUE); 
                ::UseInputWindow(mTSMDocument, FALSE); 
                err = ::ActivateTSMDocument(mTSMDocument);
              }

#ifdef DEBUG_TSM
#if 0
              NS_ASSERTION(err==noErr,"nsMacEventHandler::HandleActivateEvent: ActivateTSMDocument failed");
#endif
              printf("nsEventHandler::HandleActivateEvent: ActivateTSMDocument[%p] %s return %d\n",mTSMDocument,
              (err==noErr)?"":"ERROR", err);
#endif
              
              
              PRBool active;
              mTopLevelWidget->IsActive(&active);
              nsWindow*     focusedWidget = mTopLevelWidget;
              if (!active) {
                mEventDispatchHandler->SetActivated(focusedWidget);
                mTopLevelWidget->SetIsActive(PR_TRUE);
              }
              else if (!mEventDispatchHandler->GetActive()) {
                NS_ASSERTION(0, "We think we're active, but there is no active widget!");
                mEventDispatchHandler->SetActivated(focusedWidget);
              }
              
              // Twiddle menu bars
              nsIMenuBar* menuBar = focusedWidget->GetMenuBar();
              if (menuBar)
              {
                menuBar->Paint();
              }
              else
              {
                //ÄTODO:    if the focusedWidget doesn't have a menubar,
                //                        look all the way up to the window
                //                        until one of the parents has a menubar
              }

              // Mouse-moved events were not processed while the window was
              // inactive.  Grab the current mouse position and treat it as
              // a mouse-moved event would be.
              EventRecord eventRecord;
              ::ConvertEventRefToEventRecord(aEvent, &eventRecord);
              HandleMouseMoveEvent(eventRecord);
       }
       else if (!isActive && sLastActive == this)
       {
              sLastActive = nsnull;

              if (nsnull != gRollupListener && (nsnull != gRollupWidget) ) {
                     // If there's a widget to be rolled up, it's got to
                     // be attached to the active window, so it's OK to
                     // roll it up on any deactivate event without
                     // further checking.
                     gRollupListener->Rollup();
              }
              //
              // Deactivate the TSMDocument assoicated with this EventHandler
              //
              if (mTSMDocument) {
                // We should call FixTSMDocument() before deactivate the window.
                // see http://bugzilla.mozilla.gr.jp/show_bug.cgi?id=4135
                ResetInputState();
                // make sure we do not use input widnow even some other code turn it for default by calling 
                // ::UseInputWindow(nsnull, TRUE); 
                ::UseInputWindow(mTSMDocument, FALSE); 
                err = ::DeactivateTSMDocument(mTSMDocument);
              }

#ifdef DEBUG_TSM
              NS_ASSERTION((noErr==err)||(tsmDocNotActiveErr==err),"nsMacEventHandler::HandleActivateEvent: DeactivateTSMDocument failed");
              printf("nsEventHandler::HandleActivateEvent: DeactivateTSMDocument[%p] %s return %d\n",mTSMDocument,
              (err==noErr)?"":"ERROR", err);
#endif
              // Dispatch an NS_DEACTIVATE event 
              mEventDispatchHandler->SetDeactivated(mTopLevelWidget);
              mTopLevelWidget->SetIsActive(PR_FALSE);
       }
}

Here is the call graph for this function:

Definition at line 2147 of file nsMacEventHandler.cpp.

{
#ifdef DEBUG_TSM
       printf("HandleEndComposition\n");
#endif
       mIMEIsComposing = PR_FALSE;
       // 
       // get the focused widget [tague: may need to rethink this later]
       //
       nsWindow* focusedWidget = mEventDispatchHandler->GetActive();
       if (!focusedWidget)
              focusedWidget = mTopLevelWidget;
       
       //
       // create the nsCompositionEvent
       //
       nsCompositionEvent compositionEvent(PR_TRUE, NS_COMPOSITION_END,
                                      focusedWidget);
       compositionEvent.time = PR_IntervalNow();

       return(focusedWidget->DispatchWindowEvent(compositionEvent));
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsMacEventHandler::HandleKeyModifierEvent ( EventHandlerCallRef  aHandlerCallRef,
EventRef  aEvent 
) [virtual]

Definition at line 2407 of file nsMacEventHandler.cpp.

{
  ClearLastMouseUp();

  PRBool handled = PR_FALSE;
  nsWindow* focusedWidget = mEventDispatchHandler->GetActive();
  if (!focusedWidget)
    focusedWidget = mTopLevelWidget;

  PRUint32 modifiers = 0;
  OSStatus err = ::GetEventParameter(aEvent, kEventParamKeyModifiers,
                                     typeUInt32, NULL,
                                     sizeof(modifiers), NULL,
                                     &modifiers);
  NS_ASSERTION(err == noErr, "Could not get kEventParamKeyModifiers");

  typedef struct {
    PRUint32 modifierBit;
    PRUint32 keycode;
  } ModifierToKeycode;
  const ModifierToKeycode kModifierToKeycodeTable[] = {
    { shiftKey,   NS_VK_SHIFT },
    { controlKey, NS_VK_CONTROL },
    { optionKey,  NS_VK_ALT },
    { cmdKey,     NS_VK_META },
  };
  const PRUint32 kModifierCount = sizeof(kModifierToKeycodeTable) /
                                  sizeof(ModifierToKeycode);

  // This will be a null event, but include it anyway because it'll still have
  // good when, where, and modifiers fields, and because it's present in other
  // NS_KEY_DOWN and NS_KEY_UP events.
  EventRecord eventRecord;
  ::ConvertEventRefToEventRecord(aEvent, &eventRecord);

  for(PRUint32 i = 0 ; i < kModifierCount ; i++) {
    PRUint32 modifierBit = kModifierToKeycodeTable[i].modifierBit;
    if ((modifiers & modifierBit) != (mLastModifierState & modifierBit)) {
      PRUint32 message = ((modifiers & modifierBit) != 0 ? NS_KEY_DOWN :
                                                           NS_KEY_UP);
      nsKeyEvent upDownEvent(PR_TRUE, message, nsnull);
      upDownEvent.time =      PR_IntervalNow();
      upDownEvent.widget =    focusedWidget;
      upDownEvent.nativeMsg = (void*)&eventRecord;
      upDownEvent.isShift =   ((modifiers & shiftKey) != 0);
      upDownEvent.isControl = ((modifiers & controlKey) != 0);
      upDownEvent.isAlt =     ((modifiers & optionKey) != 0);
      upDownEvent.isMeta =    ((modifiers & cmdKey) != 0);
      upDownEvent.keyCode =   kModifierToKeycodeTable[i].keycode;
      upDownEvent.charCode =  0;
      handled |= focusedWidget->DispatchWindowEvent(upDownEvent);

      // No need to preventDefault additional events.  Although
      // kEventRawKeyModifiersChanged can carry multiple modifiers going
      // up or down, Gecko treats them independently.
 
      // Stop if focus has changed.
      nsWindow* checkFocusedWidget = mEventDispatchHandler->GetActive();
      if (!checkFocusedWidget)
        checkFocusedWidget = mTopLevelWidget;

      if (checkFocusedWidget != focusedWidget)
        break;
    }
  }

  mLastModifierState = modifiers;
  return handled;
}

Here is the call graph for this function:

PRBool nsMacEventHandler::HandleKeyUpDownEvent ( EventHandlerCallRef  aHandlerCallRef,
EventRef  aEvent 
) [virtual]

Definition at line 2259 of file nsMacEventHandler.cpp.

{
  ClearLastMouseUp();

  PRUint32 eventKind = ::GetEventKind(aEvent);
  NS_ASSERTION(eventKind == kEventRawKeyDown ||
               eventKind == kEventRawKeyUp,
               "Unknown event kind");

  OSStatus err = noErr;

  PRBool sendToTSM = PR_FALSE;
  if (eventKind == kEventRawKeyDown) {
    if (IsPluginFocused()) {
      if (mTSMDocument != ::TSMGetActiveDocument()) {
        // If some TSM document other than the one that we use for this window
        // is active, first try to call through to the TSM handler during a
        // keydown.  This can happen if a plugin installs its own TSM handler
        // and activates its own TSM document.
        // This is done early, before dispatching NS_KEY_DOWN because the
        // plugin will receive the keyDown event carried in the NS_KEY_DOWN.
        // If an IME session is active, this could cause the plugin to accept
        // both raw keydowns and text input from the IME session as input.
        err = ::CallNextEventHandler(aHandlerCallRef, aEvent);
        if (err == noErr) {
          // Someone other than us handled the event.  Don't send NS_KEY_DOWN.
          return PR_TRUE;
        }

        // No foreign handlers did anything.  Leave sendToTSM false so that
        // no subsequent attempts to call through to the foreign handler will
        // be made.
      }
      else {
        // The TSM document matches the one corresponding to the window.
        // An NS_KEY_DOWN event will be sent, and after that, it will be put
        // back into the handler chain to go to the TSM input handlers.
        // This assumes that the TSM handler is still ours, or that if
        // something else changed the TSM handler, that the new handler will
        // at least call through to ours.
        sendToTSM = PR_TRUE;
      }
    } else {
      // If the focus isn't currently in any plugin and we have a TSM document
      // that isn't currently active, activate it.  This helps with plugins
      // that set their own TSM document and then don't set it back, or don't
      // set it back correctly.  This should always have been the browser's
      // responsibility in any case.  This change resolves bmo bug 355071, and
      // also bmo bugs 345010 and (possibly) 318139 on the 1.8.1 branch.
      if (mTSMDocument && (mTSMDocument != ::TSMGetActiveDocument()))
        ::ActivateTSMDocument(mTSMDocument);
      sendToTSM = PR_TRUE;
    }
  }

  PRBool handled = PR_FALSE;
  nsWindow* focusedWidget = mEventDispatchHandler->GetActive();
  if (!focusedWidget)
    focusedWidget = mTopLevelWidget;

  PRUint32 modifiers = 0;
  err = ::GetEventParameter(aEvent, kEventParamKeyModifiers,
                            typeUInt32, NULL,
                            sizeof(modifiers), NULL,
                            &modifiers);
  NS_ASSERTION(err == noErr, "Could not get kEventParamKeyModifiers");

  PRUint32 keyCode = 0;
  err = ::GetEventParameter(aEvent, kEventParamKeyCode,
                            typeUInt32, NULL,
                            sizeof(keyCode), NULL,
                            &keyCode);
  NS_ASSERTION(err == noErr, "Could not get kEventParamKeyCode");

  PRUint8 charCode = 0;
  ::GetEventParameter(aEvent, kEventParamKeyMacCharCodes,
                      typeChar, NULL,
                      sizeof(charCode), NULL,
                      &charCode);
  // Failure is not a fatal condition.

  // The event's nativeMsg field historically held an EventRecord.  Some
  // consumers (plugins) rely on this behavior.  Note that
  // ConvertEventRefToEventRecord can return false and produce a null
  // event record in some cases, such as when entering an IME session.
  EventRecord eventRecord;
  ::ConvertEventRefToEventRecord(aEvent, &eventRecord);

  // kEventRawKeyDown or kEventRawKeyUp only

  PRUint32 message = (eventKind == kEventRawKeyUp ? NS_KEY_UP : NS_KEY_DOWN);
  nsKeyEvent upDownEvent(PR_TRUE, message, nsnull);
  upDownEvent.time =      PR_IntervalNow();
  upDownEvent.widget =    focusedWidget;
  upDownEvent.nativeMsg = (void*)&eventRecord;
  upDownEvent.isShift =   ((modifiers & shiftKey) != 0);
  upDownEvent.isControl = ((modifiers & controlKey) != 0);
  upDownEvent.isAlt =     ((modifiers & optionKey) != 0);
  upDownEvent.isMeta =    ((modifiers & cmdKey) != 0);
  upDownEvent.keyCode =   ConvertMacToRaptorKeyCode(charCode, keyCode,
                                                    modifiers);
  upDownEvent.charCode =  0;
  handled = focusedWidget->DispatchWindowEvent(upDownEvent);

  if (eventKind == kEventRawKeyUp)
    return handled;

  // kEventRawKeyDown only.  Prepare for a possible NS_KEY_PRESS event.

  nsWindow* checkFocusedWidget = mEventDispatchHandler->GetActive();
  if (!checkFocusedWidget)
    checkFocusedWidget = mTopLevelWidget;

  // Set a flag indicating that NS_KEY_PRESS events should not be dispatched,
  // because focus changed.
  PRBool lastIgnore = PR_FALSE;
  if (checkFocusedWidget != focusedWidget) {
    lastIgnore = mKeyIgnore;
    mKeyIgnore = PR_TRUE;
  }

  // Set a flag indicating that the NS_KEY_DOWN event came back with
  // preventDefault, and NS_KEY_PRESS events should have the same flag set.
  PRBool lastHandled = PR_FALSE;
  if (handled) {
    lastHandled = mKeyHandled;
    mKeyHandled = PR_TRUE;
  }

  if (sendToTSM) {
    // The event needs further processing.
    //  - If no input method is active, an event will be delivered to the
    //    kEventTextInputUnicodeForKeyEvent handler, which will call
    //    HandleUKeyEvent, which takes care of dispatching NS_KEY_PRESS events.
    //  - If an input method is active, an event will be delivered to the
    //    kEventTextInputUpdateActiveInputArea handler, which will call
    //    UnicodeHandleUpdateInputArea to handle the input session.
    ::CallNextEventHandler(aHandlerCallRef, aEvent);
  }

  mKeyHandled = lastHandled;
  mKeyIgnore = lastIgnore;

  return handled;
}

Here is the call graph for this function:

PRBool nsMacEventHandler::HandleMouseDownEvent ( EventRecord &  aOSEvent) [protected, virtual]

Definition at line 1424 of file nsMacEventHandler.cpp.

{    
       PRBool retVal = PR_FALSE;

       WindowPtr            whichWindow;
       short partCode = ::FindWindow(aOSEvent.where, &whichWindow);

  PRBool ignoreClickInContent = PR_FALSE;

  // Deal with any popups (comboboxes, xul popups, XP menus, etc) that might have to 
  // be closed down since they are implemented as stand-alone windows on top of
  // the current content window. If the click is not in the front window, we need to
  // hide the popup if one is visible. Furthermore, we want to ignore the click that
  // caused the popup to close and not pass it along to gecko.
  if ( whichWindow != ::FrontWindow() ) {
    if ( gRollupListener && gRollupWidget ) {
      PRBool rollup = PR_TRUE;

      // if we're dealing with menus, we probably have submenus and we don't want
      // to rollup if the click is in a parent menu of the current submenu.
      nsCOMPtr<nsIMenuRollup> menuRollup ( do_QueryInterface(gRollupListener) );
      if ( menuRollup ) {
        nsCOMPtr<nsISupportsArray> widgetChain;
        menuRollup->GetSubmenuWidgetChain ( getter_AddRefs(widgetChain) );
        if ( widgetChain ) {      
          PRUint32 count = 0;
          widgetChain->Count(&count);
          for ( PRUint32 i = 0; i < count; ++i ) {
            nsCOMPtr<nsISupports> genericWidget;
            widgetChain->GetElementAt ( i, getter_AddRefs(genericWidget) );
            nsCOMPtr<nsIWidget> widget ( do_QueryInterface(genericWidget) );
            if ( widget ) {
              if ( NS_REINTERPRET_CAST(WindowPtr,widget->GetNativeData(NS_NATIVE_DISPLAY)) == whichWindow )
                 rollup = PR_FALSE;
            }         
          } // foreach parent menu widget
        }
      } // if rollup listener knows about menus
      
      // if we've determined that we should still rollup everything, do it.
      if ( rollup ) {
                     gRollupListener->Rollup();
                     ignoreClickInContent = PR_TRUE;
         }
 
              } // if a popup is active
  } // if click in a window not the frontmost
 
       switch (partCode)
       {
              case inDrag:
              {
                     Point macPoint;
                     Rect portRect;
                     ::GetWindowPortBounds(whichWindow, &portRect);
                     macPoint = topLeft(portRect);
                     ::LocalToGlobal(&macPoint);
                     mTopLevelWidget->MoveToGlobalPoint(macPoint.h, macPoint.v);
                     retVal = PR_TRUE;
                     break;
              }

              case inGrow:
              {
      ResizeEvent ( whichWindow );
      retVal = PR_TRUE;
      break;
              }

              case inGoAway:
              {
                     ResetInputState();   // IM:TEXT 7-23 said we need to call FixTSMDocument when we go away...
                     if (nsnull != gRollupListener && (nsnull != gRollupWidget) ) {
                            gRollupListener->Rollup();
                     }
                     mEventDispatchHandler->DispatchGuiEvent(mTopLevelWidget, NS_XUL_CLOSE);             
                     // mTopLevelWidget->Destroy(); (this, by contrast, would immediately close the window)
                     retVal = PR_TRUE;
                     break;
              }

              case inContent:
              {
                     // don't allow clicks that rolled up a popup through to the content area.
                     if ( ignoreClickInContent )
                            break;
                                          
                     nsMouseEvent mouseEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);
                     PRUint32 mouseButton = NS_MOUSE_LEFT_BUTTON_DOWN;
                     if ( aOSEvent.modifiers & controlKey )
                       mouseButton = NS_MOUSE_RIGHT_BUTTON_DOWN;

                     // We've hacked our events to include the button.
                     // Normally message is undefined in mouse click/drag events.
                     if ( aOSEvent.message == kEventMouseButtonSecondary )
                       mouseButton = NS_MOUSE_RIGHT_BUTTON_DOWN;
                     if ( aOSEvent.message == kEventMouseButtonTertiary )
                       mouseButton = NS_MOUSE_MIDDLE_BUTTON_DOWN;

                     ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton);

                     nsCOMPtr<nsIWidget> kungFuDeathGrip ( mouseEvent.widget );            // ensure widget doesn't go away
                     nsWindow* widgetHit = NS_STATIC_CAST(nsWindow*, mouseEvent.widget);   //   while we're processing event
                     if (widgetHit)
                     {        
                            // set the activation and focus on the widget hit, if it accepts it
                            {
                                   nsMouseEvent mouseActivateEvent(PR_TRUE, 0, nsnull,
                                          nsMouseEvent::eReal);
          ConvertOSEventToMouseEvent(aOSEvent, mouseActivateEvent, NS_MOUSE_ACTIVATE);
                                   widgetHit->DispatchMouseEvent(mouseActivateEvent);
                            }

                            // dispatch the event
                            retVal = widgetHit->DispatchMouseEvent(mouseEvent);
                            
                            // if we're a control-click, send in an additional NS_CONTEXTMENU event
                            // after the mouse down.
                            if ( mouseButton == NS_MOUSE_RIGHT_BUTTON_DOWN ) {
                     nsMouseEvent contextMenuEvent(PR_TRUE, 0, nsnull,
                                        nsMouseEvent::eReal);
                     ConvertOSEventToMouseEvent(aOSEvent, contextMenuEvent, NS_CONTEXTMENU);
                     contextMenuEvent.isControl = PR_FALSE;                         
                                   widgetHit->DispatchMouseEvent(contextMenuEvent);
        } 

        // If we found a widget to dispatch to, say we handled the event.
        // The meaning of the result of DispatchMouseEvent() is ambiguous.
        // In Gecko terms, it means "continue processing", but that doesn't
        // say if the event was really handled (which is a simplistic notion
        // to Gecko).
        retVal = PR_TRUE;
                     }
                                          
                     mEventDispatchHandler->SetWidgetHit(widgetHit);
                     mMouseInWidgetHit = PR_TRUE;
                     break;
              }


              case inZoomIn:
              case inZoomOut:
              {
                     mEventDispatchHandler->DispatchSizeModeEvent(mTopLevelWidget,
                            partCode == inZoomIn ? nsSizeMode_Normal : nsSizeMode_Maximized);
                     retVal = PR_TRUE;
                     break;
              }

    case inToolbarButton:           // we get this part on Mac OS X only
      mEventDispatchHandler->DispatchGuiEvent(mTopLevelWidget, NS_OS_TOOLBAR);             
      retVal = PR_TRUE;
      break;
       }
       return retVal;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsMacEventHandler::HandleMouseMoveEvent ( EventRecord &  aOSEvent) [protected, virtual]

Definition at line 1633 of file nsMacEventHandler.cpp.

{
       nsWindow* lastWidgetHit = mEventDispatchHandler->GetWidgetHit();
       nsWindow* lastWidgetPointed = mEventDispatchHandler->GetWidgetPointed();
  
       PRBool retVal = PR_FALSE;

       WindowRef wind = reinterpret_cast<WindowRef>(mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY));
       nsWindowType windowType;
       mTopLevelWidget->GetWindowType(windowType);
       if (!::IsWindowActive(wind) && windowType != eWindowType_popup)
              return retVal;

       nsMouseEvent mouseEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);
       ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, NS_MOUSE_MOVE);
       if (lastWidgetHit)
       {
              Point macPoint = aOSEvent.where;
              nsGraphicsUtils::SafeSetPortWindowPort(wind);
              {
                     StOriginSetter  originSetter(wind);
                     ::GlobalToLocal(&macPoint);
              }
              PRBool inWidgetHit = lastWidgetHit->PointInWidget(macPoint);
              if (mMouseInWidgetHit != inWidgetHit)
              {
                     mMouseInWidgetHit = inWidgetHit;
                     mouseEvent.message = (inWidgetHit ? NS_MOUSE_ENTER : NS_MOUSE_EXIT);
              }
              lastWidgetHit->DispatchMouseEvent(mouseEvent);
              retVal = PR_TRUE;
       }
       else
       {
              nsWindow* widgetPointed = (nsWindow*)mouseEvent.widget;
              nsCOMPtr<nsIWidget> kungFuDeathGrip(widgetPointed);     // Protect during processing
              if (widgetPointed != lastWidgetPointed)
              {
                     if (lastWidgetPointed)
                     {
        // We need to convert the coords to be relative to lastWidgetPointed.
        nsPoint widgetHitPoint = mouseEvent.point;

        Point macPoint = aOSEvent.where;
        nsGraphicsUtils::SafeSetPortWindowPort(wind);

        {
          StOriginSetter originSetter(wind);
          ::GlobalToLocal(&macPoint);
        }

        nsPoint lastWidgetHitPoint(macPoint.h, macPoint.v);

          nsRect bounds;
          lastWidgetPointed->GetBounds(bounds);
          nsPoint widgetOrigin(bounds.x, bounds.y);
          lastWidgetPointed->LocalToWindowCoordinate(widgetOrigin);
          lastWidgetHitPoint.MoveBy(-widgetOrigin.x, -widgetOrigin.y);
                            mouseEvent.widget = lastWidgetPointed;
                            mouseEvent.point = lastWidgetHitPoint;
                            mouseEvent.message = NS_MOUSE_EXIT;
                            lastWidgetPointed->DispatchMouseEvent(mouseEvent);
                            retVal = PR_TRUE;

                            mouseEvent.point = widgetHitPoint;
                     }

      mEventDispatchHandler->SetWidgetPointed(widgetPointed);
#if TRACK_MOUSE_LOC
      mEventDispatchHandler->SetGlobalPoint(aOSEvent.where);
#endif

                     if (widgetPointed)
                     {
                            mouseEvent.widget = widgetPointed;
                            mouseEvent.message = NS_MOUSE_ENTER;
                            widgetPointed->DispatchMouseEvent(mouseEvent);
                            retVal = PR_TRUE;
                     }
              }
              else
              {
                     if (widgetPointed)
                     {
                            widgetPointed->DispatchMouseEvent(mouseEvent);
                            retVal = PR_TRUE;
                     }
              }
       }

       return retVal;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsMacEventHandler::HandleMouseUpEvent ( EventRecord &  aOSEvent) [protected, virtual]

Definition at line 1587 of file nsMacEventHandler.cpp.

{
       PRBool retVal = PR_FALSE;

       nsMouseEvent mouseEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);
       PRUint32 mouseButton = NS_MOUSE_LEFT_BUTTON_UP;

       // We've hacked our events to include the button.
       // Normally message is undefined in mouse click/drag events.
       if ( aOSEvent.message == kEventMouseButtonSecondary )
              mouseButton = NS_MOUSE_RIGHT_BUTTON_UP;
       if ( aOSEvent.message == kEventMouseButtonTertiary )
              mouseButton = NS_MOUSE_MIDDLE_BUTTON_UP;

       ConvertOSEventToMouseEvent(aOSEvent, mouseEvent, mouseButton);

       nsWindow* widgetReleased = (nsWindow*)mouseEvent.widget;
       nsWindow* widgetHit = mEventDispatchHandler->GetWidgetHit();

       if ( widgetReleased )
       {
              widgetReleased->DispatchMouseEvent(mouseEvent);
              // If we found a widget to dispatch the event to, say that we handled it
              // (see comments in HandleMouseDownEvent()).
              retVal = PR_TRUE;
       }
       
       if ( widgetReleased != widgetHit ) {
         //XXX we should send a mouse exit event to the last widget, right?!?! But
         //XXX we cannot use the same event, because the coordinates we just
         //XXX computed are in the wrong window/widget coordinate space. I'm 
         //XXX unclear what we should do in this case. (pinkerton).
       }
       
       mEventDispatchHandler->SetWidgetHit(nsnull);

       return retVal;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMacEventHandler::HandleOffsetToPosition ( long  offset,
Point *  position 
) [virtual]

Definition at line 1867 of file nsMacEventHandler.cpp.

{
       thePoint->v = mIMEPos.y;
       thePoint->h = mIMEPos.x;
       //printf("local (x,y) = (%d, %d)\n", thePoint->h, thePoint->v);
       WindowRef wind = reinterpret_cast<WindowRef>(mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY));
       nsGraphicsUtils::SafeSetPortWindowPort(wind);
       Rect savePortRect;
       ::GetWindowPortBounds(wind, &savePortRect);
       ::LocalToGlobal(thePoint);
       //printf("global (x,y) = (%d, %d)\n", thePoint->h, thePoint->v);

       return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsMacEventHandler::HandleOSEvent ( EventRecord &  aOSEvent) [virtual]

Definition at line 408 of file nsMacEventHandler.cpp.

{
       PRBool retVal = PR_FALSE;

       switch (aOSEvent.what)
       {
              case mouseDown:
                     retVal = HandleMouseDownEvent(aOSEvent);
                     break;

              case mouseUp:
                     retVal = HandleMouseUpEvent(aOSEvent);
                     break;

              case osEvt:
              {
                     unsigned char eventType = ((aOSEvent.message >> 24) & 0x00ff);
                     if (eventType == mouseMovedMessage)
                     {
                            retVal = HandleMouseMoveEvent(aOSEvent);
                     }
              }
              break;
       }

       return retVal;
}

Here is the call graph for this function:

long nsMacEventHandler::HandlePositionToOffset ( Point  aPoint,
short *  regionClass 
) [virtual]

Definition at line 1856 of file nsMacEventHandler.cpp.

{
       *regionClass = kTSMOutsideOfBody;
       return 0;
}

Here is the caller graph for this function:

Definition at line 2102 of file nsMacEventHandler.cpp.

{
#ifdef DEBUG_TSM
       printf("HandleStartComposition\n");
#endif
       mIMEIsComposing = PR_TRUE;
       if(nsnull == mIMECompositionStr)
              mIMECompositionStr = new nsAutoString();
       NS_ASSERTION(mIMECompositionStr, "cannot allocate mIMECompositionStr");
       if(nsnull == mIMECompositionStr)
       {
              return NS_ERROR_OUT_OF_MEMORY;
       }      
       // 
       // get the focused widget [tague: may need to rethink this later]
       //
       nsWindow* focusedWidget = mEventDispatchHandler->GetActive();
       if (!focusedWidget)
              focusedWidget = mTopLevelWidget;
       
       //
       // create the nsCompositionEvent
       //
       nsCompositionEvent compositionEvent(PR_TRUE, NS_COMPOSITION_START,
                                      focusedWidget);
       compositionEvent.time = PR_IntervalNow();

       nsresult res = focusedWidget->DispatchWindowEvent(compositionEvent);
       if(NS_SUCCEEDED(res)) {
              mIMEPos.x = compositionEvent.theReply.mCursorPosition.x;
              mIMEPos.y = compositionEvent.theReply.mCursorPosition.y
                        + compositionEvent.theReply.mCursorPosition.height;
              focusedWidget->LocalToWindowCoordinate(mIMEPos);
#ifdef DEBUG_TSM
              printf("HandleStartComposition reply (%d,%d)\n", mIMEPos.x , mIMEPos.y);
#endif
       }
       return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMacEventHandler::HandleTextEvent ( PRUint32  textRangeCount,
nsTextRangeArray  textRangeArray 
) [protected, virtual]

Definition at line 2175 of file nsMacEventHandler.cpp.

{
#ifdef DEBUG_TSM
       printf("HandleTextEvent\n");
       PRUint32 i;
       printf("text event \n[");
       const PRUnichar *ubuf = mIMECompositionStr->get();
       for(i=0; '\0' != *ubuf; i++)
              printf("U+%04X ", *ubuf++);
       printf("] len = %d\n",i);
       if(textRangeCount > 0)
       {
              for(i=0;i<textRangeCount;i++ )
              {
                     NS_ASSERTION((NS_TEXTRANGE_CARETPOSITION!=textRangeArray[i].mRangeType) ||
                                           (textRangeArray[i].mStartOffset == textRangeArray[i].mEndOffset),
                                           "start != end in CaretPosition");
                     NS_ASSERTION(
                            (NS_TEXTRANGE_CARETPOSITION==textRangeArray[i].mRangeType)||
                            (NS_TEXTRANGE_RAWINPUT==textRangeArray[i].mRangeType)||
                            (NS_TEXTRANGE_SELECTEDRAWTEXT==textRangeArray[i].mRangeType)||
                            (NS_TEXTRANGE_CONVERTEDTEXT==textRangeArray[i].mRangeType)||
                            (NS_TEXTRANGE_SELECTEDCONVERTEDTEXT==textRangeArray[i].mRangeType),
                            "illegal range type");
                     static char *name[6] =
                     {
                            "Unknown",
                            "CaretPosition", 
                            "RawInput", 
                            "SelectedRawText",
                            "ConvertedText",
                            "SelectedConvertedText"
                     };
                     printf("[%d,%d]=%s\n", 
                     textRangeArray[i].mStartOffset, 
                     textRangeArray[i].mEndOffset,
                     ((textRangeArray[i].mRangeType<=NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) ?
                            name[textRangeArray[i].mRangeType] : name[0])
                     );
              }
       }
#endif
       // 
       // get the focused widget [tague: may need to rethink this later]
       //
       nsWindow* focusedWidget = mEventDispatchHandler->GetActive();
       if (!focusedWidget)
              focusedWidget = mTopLevelWidget;
       
       //
       // create the nsTextEvent
       //
       nsTextEvent textEvent(PR_TRUE, NS_TEXT_TEXT, focusedWidget);
       textEvent.time = PR_IntervalNow();
       textEvent.theText = mIMECompositionStr->get();
       textEvent.rangeCount = textRangeCount;
       textEvent.rangeArray = textRangeArray;

       nsresult res = NS_OK;
       if (NS_SUCCEEDED(res = focusedWidget->DispatchWindowEvent(textEvent))) {
              mIMEPos.x = textEvent.theReply.mCursorPosition.x;
              mIMEPos.y = textEvent.theReply.mCursorPosition.y +
                          textEvent.theReply.mCursorPosition.height;
              mTopLevelWidget->LocalToWindowCoordinate(mIMEPos);
#ifdef DEBUG_TSM
              printf("HandleTextEvent reply (%d,%d)\n", mIMEPos.x , mIMEPos.y);
#endif
       } 
       return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsMacEventHandler::HandleUKeyEvent ( const PRUnichar text,
long  charCount,
EventRecord &  aOSEvent 
) [virtual]

Definition at line 1089 of file nsMacEventHandler.cpp.

{
  ClearLastMouseUp();

  // The focused widget changed in HandleKeyUpDownEvent, so no NS_KEY_PRESS
  // events should be generated.
  if (mKeyIgnore)
    return PR_FALSE;

  PRBool handled = PR_FALSE;

  // get the focused widget
  nsWindow* focusedWidget = mEventDispatchHandler->GetActive();
  if (!focusedWidget)
    focusedWidget = mTopLevelWidget;
  
  // simulate key press events
  if (!IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8))
  {
    // it is a message with text, send all the unicode characters
    PRInt32 i;
    for (i = 0; i < charCount; i++)
    {
      nsKeyEvent keyPressEvent(PR_TRUE, NS_KEY_PRESS, nsnull);
      InitializeKeyEvent(keyPressEvent, aOSEvent, focusedWidget, NS_KEY_PRESS, PR_FALSE);
      keyPressEvent.charCode = text[i];

      // If keydown default was prevented, do same for keypress
      if (mKeyHandled)
        keyPressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;

      // control key is special in that it doesn't give us letters
      // it generates a charcode of 0x01 for control-a
      // so we offset to do the right thing for gecko
      // this doesn't happen for us in InitializeKeyEvent because we pass
      // PR_FALSE so no character translation occurs.
      // I'm guessing we don't want to do the translation there because
      // translation already occurred for the string passed to this method.
      if (keyPressEvent.isControl && keyPressEvent.charCode <= 26)       
      {
        if (keyPressEvent.isShift)
          keyPressEvent.charCode += 'A' - 1;
        else
          keyPressEvent.charCode += 'a' - 1;
      }

      // this block of code is triggered when user presses
      // a combination such as command-shift-M
      if (keyPressEvent.isShift && keyPressEvent.charCode <= 'z' && keyPressEvent.charCode >= 'a') 
        keyPressEvent.charCode -= 32;

      // before we dispatch a key, check if it's the context menu key.
      // If so, send a context menu event instead.
      if ( IsContextMenuKey(keyPressEvent) ) {
        nsMouseEvent contextMenuEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);
        ConvertKeyEventToContextMenuEvent(&keyPressEvent, &contextMenuEvent);
        handled |= focusedWidget->DispatchWindowEvent(contextMenuEvent);
      }
      else {
        // Send ordinary keypresses
        handled |= focusedWidget->DispatchWindowEvent(keyPressEvent);
      }
    }
  }
  else {
    // "Special" keys, only send one event based on the keycode
    nsKeyEvent keyPressEvent(PR_TRUE, NS_KEY_PRESS, nsnull);
    InitializeKeyEvent(keyPressEvent, aOSEvent, focusedWidget, NS_KEY_PRESS, PR_FALSE);
    handled = focusedWidget->DispatchWindowEvent(keyPressEvent);
  }
  return handled;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMacEventHandler::HandleUnicodeGetSelectedText ( nsAString &  outString) [virtual]

Definition at line 2077 of file nsMacEventHandler.cpp.

{
  outString.Truncate(0);
  nsWindow* focusedWidget = mEventDispatchHandler->GetActive();
  if (!focusedWidget)
    focusedWidget = mTopLevelWidget;

  nsReconversionEvent reconversionEvent(PR_TRUE, NS_RECONVERSION_QUERY,
                                        focusedWidget);
  reconversionEvent.time = PR_IntervalNow();

  nsresult res = focusedWidget->DispatchWindowEvent(reconversionEvent);

  if (NS_SUCCEEDED(res)) {
     outString.Assign(reconversionEvent.theReply.mReconversionString);
     nsMemory::Free(reconversionEvent.theReply.mReconversionString);
  } 
  return res; 
  
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsMacEventHandler::InitializeKeyEvent ( nsKeyEvent aKeyEvent,
EventRecord &  aOSEvent,
nsWindow aFocusedWidget,
PRUint32  aMessage,
PRBool  aConvertChar = PR_TRUE 
) [protected]

Definition at line 826 of file nsMacEventHandler.cpp.

{
       //
       // initalize the basic message parts
       //
       aKeyEvent.time                            = PR_IntervalNow();
       
       //
       // initalize the GUI event parts
       //
  aKeyEvent.widget = aFocusedWidget;
       aKeyEvent.nativeMsg         = (void*)&aOSEvent;
       
       //
       // nsInputEvent parts
       //
       aKeyEvent.isShift                  = ((aOSEvent.modifiers & shiftKey) != 0);
       aKeyEvent.isControl         = ((aOSEvent.modifiers & controlKey) != 0);
       aKeyEvent.isAlt                           = ((aOSEvent.modifiers & optionKey) != 0);
       aKeyEvent.isMeta            = ((aOSEvent.modifiers & cmdKey) != 0);
       
       //
       // nsKeyEvent parts
       //
  if (aMessage == NS_KEY_PRESS 
              && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) )
       {
    if (aKeyEvent.isControl)
              {
      if (aConvertChar) 
      {
                     aKeyEvent.charCode = (aOSEvent.message & charCodeMask);
        if (aKeyEvent.charCode <= 26)
                     {
          if (aKeyEvent.isShift)
                                   aKeyEvent.charCode += 'A' - 1;
                            else
                                   aKeyEvent.charCode += 'a' - 1;
        } // if (aKeyEvent.charCode <= 26)
      }
                     aKeyEvent.keyCode    = 0;
    } // if (aKeyEvent.isControl)
    else // else for if (aKeyEvent.isControl)
              {
      if (!aKeyEvent.isMeta)
                     {
                            aKeyEvent.isControl = aKeyEvent.isAlt = aKeyEvent.isMeta = 0;
      } // if (!aKeyEvent.isMeta)
    
                     aKeyEvent.keyCode    = 0;
      if (aConvertChar) 
      {
                     aKeyEvent.charCode = ConvertKeyEventToUnicode(aOSEvent);
        if (aKeyEvent.isShift && aKeyEvent.charCode <= 'z' && aKeyEvent.charCode >= 'a') 
        {
                       aKeyEvent.charCode -= 32;
                     }
                     NS_ASSERTION(0 != aKeyEvent.charCode, "nsMacEventHandler::InitializeKeyEvent: ConvertKeyEventToUnicode returned 0.");
      }
    } // else for if (aKeyEvent.isControl)
       } // if (message == NS_KEY_PRESS && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) )
       else
       {
              aKeyEvent.keyCode = ConvertMacToRaptorKeyCode(aOSEvent.message & charCodeMask, (aOSEvent.message & keyCodeMask) >> 8, aOSEvent.modifiers);
              aKeyEvent.charCode = 0;
       } // else for  if (message == NS_KEY_PRESS && !IsSpecialRaptorKey((aOSEvent.message & keyCodeMask) >> 8) )
  
  //
  // obscure cursor if appropriate
  //
  if (aMessage == NS_KEY_PRESS 
              && !aKeyEvent.isMeta 
              && aKeyEvent.keyCode != nsIDOMKeyEvent::DOM_VK_PAGE_UP 
              && aKeyEvent.keyCode != nsIDOMKeyEvent::DOM_VK_PAGE_DOWN
              // also consider:  function keys and sole modifier keys
       ) 
       {
    ::ObscureCursor();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsMacEventHandler::InitializeMouseEvent ( nsMouseEvent aMouseEvent,
nsPoint aPoint,
PRInt16  aModifiers,
PRUint32  aClickCount 
) [protected]

Definition at line 504 of file nsMacEventHandler.cpp.

{
  // nsEvent
  aMouseEvent.point      = aPoint;
  aMouseEvent.time       = PR_IntervalNow();

  // nsInputEvent
  aMouseEvent.isShift    = ((aModifiers & shiftKey)   != 0);
  aMouseEvent.isControl  = ((aModifiers & controlKey) != 0);
  aMouseEvent.isAlt      = ((aModifiers & optionKey)  != 0);
  aMouseEvent.isMeta     = ((aModifiers & cmdKey)     != 0);

  // nsMouseEvent
  aMouseEvent.clickCount = aClickCount;
}

Here is the caller graph for this function:

Definition at line 2490 of file nsMacEventHandler.cpp.

{
  PRBool retval = PR_FALSE;
  nsIWidget* widget = mEventDispatchHandler->GetActive();
  nsIDocument *doc = nsToolkit::GetDocumentFor(widget);
  if (doc) {
    nsIPresShell* presShell = doc->GetShellAt(0);
    nsIEventStateManager* esm = presShell->GetPresContext()->EventStateManager();
    nsIFrame *focusedFrame = nsnull;
    esm->GetFocusedFrame(&focusedFrame);
    if (focusedFrame) {
      nsIObjectFrame *pluginFrame;
      // There's no need to call Release() on objectIFrame, since AddRef()
      // and Release() don't work on frames.
      if (NS_SUCCEEDED(CallQueryInterface(focusedFrame, &pluginFrame)))
        retval = PR_TRUE;
    }
  }
  return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsMacEventHandler::IsSpecialRaptorKey ( UInt32  macKeyCode) [protected, virtual]

Definition at line 917 of file nsMacEventHandler.cpp.

{
       PRBool isSpecial;

       // 
       // this table is used to determine which keys are special and should not generate a charCode
       //     
       switch (macKeyCode)
       {
// modifiers. We don't get separate events for these
// yet
              case kEscapeKeyCode:                      isSpecial = PR_TRUE; break;
              case kShiftKeyCode:                              isSpecial = PR_TRUE; break;
              case kCommandKeyCode:       isSpecial = PR_TRUE; break;
              case kCapsLockKeyCode:                    isSpecial = PR_TRUE; break;
              case kControlKeyCode:                            isSpecial = PR_TRUE; break;
              case kOptionkeyCode:                      isSpecial = PR_TRUE; break;
              case kClearKeyCode:                              isSpecial = PR_TRUE; break;

// function keys
              case kF1KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF2KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF3KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF4KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF5KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF6KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF7KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF8KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF9KeyCode:                                 isSpecial = PR_TRUE; break;
              case kF10KeyCode:                                isSpecial = PR_TRUE; break;
              case kF11KeyCode:                                isSpecial = PR_TRUE; break;
              case kF12KeyCode:                                isSpecial = PR_TRUE; break;
              case kPauseKeyCode:                       isSpecial = PR_TRUE; break;
              case kScrollLockKeyCode:    isSpecial = PR_TRUE; break;
              case kPrintScreenKeyCode:   isSpecial = PR_TRUE; break;

              case kHelpKeyCode:                               isSpecial = PR_TRUE; break;
              case kDeleteKeyCode:                      isSpecial = PR_TRUE; break;
              case kTabKeyCode:                                       isSpecial = PR_TRUE; break;
              case kBackspaceKeyCode:     isSpecial = PR_TRUE; break;

              case kHomeKeyCode:                               isSpecial = PR_TRUE; break; 
              case kEndKeyCode:                                       isSpecial = PR_TRUE; break;
              case kPageUpKeyCode:                      isSpecial = PR_TRUE; break;
              case kPageDownKeyCode:                    isSpecial = PR_TRUE; break;
              case kLeftArrowKeyCode:                   isSpecial = PR_TRUE; break;
              case kRightArrowKeyCode:           isSpecial = PR_TRUE; break;
              case kUpArrowKeyCode:                            isSpecial = PR_TRUE; break;
              case kDownArrowKeyCode:                   isSpecial = PR_TRUE; break;
              case kReturnKeyCode:        isSpecial = PR_TRUE; break;
              case kEnterKeyCode:         isSpecial = PR_TRUE; break;
              case kPowerbookEnterKeyCode: isSpecial = PR_TRUE; break;

              default:                                                isSpecial = PR_FALSE; break;
       }
       return isSpecial;
}

Here is the caller graph for this function:

Definition at line 2245 of file nsMacEventHandler.cpp.

{
       OSErr err = noErr;
       if (mTSMDocument) {
              // make sure we do not use input widnow even some other code turn it for default by calling 
              // ::UseInputWindow(nsnull, TRUE); 
              ::UseInputWindow(mTSMDocument, FALSE); 
              err = ::FixTSMDocument(mTSMDocument);
              NS_ASSERTION( (noErr==err)||(tsmDocNotActiveErr==err)||(tsmTSNotOpenErr), "Cannot FixTSMDocument");
       }
       return NS_OK; 
}

Here is the caller graph for this function:

PRBool nsMacEventHandler::ResizeEvent ( WindowRef  inWindow) [virtual]

Definition at line 1285 of file nsMacEventHandler.cpp.

{
       Rect macRect;
       ::GetWindowPortBounds ( inWindow, &macRect );
       ::LocalToGlobal(&topLeft(macRect));
       ::LocalToGlobal(&botRight(macRect));
       mTopLevelWidget->Resize(macRect.right - macRect.left,
                                macRect.bottom - macRect.top,
                                PR_FALSE,
                                PR_TRUE); // resize came from the UI via event
       if (nsnull != gRollupListener && (nsnull != gRollupWidget) )
              gRollupListener->Rollup();
       mTopLevelWidget->UserStateForResize(); // size a zoomed window and it's no longer zoomed

       return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsMacEventHandler::Scroll ( PRInt32  aDeltaY,
PRInt32  aDeltaX,
PRBool  aIsPixels,
const Point &  aMouseLoc,
nsWindow aWindow,
PRUint32  aModifiers 
) [virtual]

Definition at line 1309 of file nsMacEventHandler.cpp.

                                                                  {
  PRBool resY = ScrollAxis(nsMouseScrollEvent::kIsVertical, aDeltaY,
                           aIsPixels, aMouseLoc, aWindow, aModifiers);
  PRBool resX = ScrollAxis(nsMouseScrollEvent::kIsHorizontal, aDeltaX,
                           aIsPixels, aMouseLoc, aWindow, aModifiers);

  return resY || resX;
} // Scroll

Here is the call graph for this function:

PRBool nsMacEventHandler::ScrollAxis ( nsMouseScrollEvent::nsMouseScrollFlags  aAxis,
PRInt32  aDelta,
PRBool  aIsPixels,
const Point &  aMouseLoc,
nsWindow aWindow,
PRUint32  aModifiers 
) [protected, virtual]

Definition at line 1325 of file nsMacEventHandler.cpp.

{
  // Only scroll active windows.  Treat popups as active.
  WindowRef windowRef = NS_STATIC_CAST(WindowRef,
                         mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY));
  nsWindowType windowType;
  mTopLevelWidget->GetWindowType(windowType);
  if (!::IsWindowActive(windowRef) && windowType != eWindowType_popup)
    return PR_FALSE;

  // Figure out which widget should be scrolled by traversing the widget
  // hierarchy beginning at the root nsWindow.  aMouseLoc should be
  // relative to the origin of this nsWindow.  If the scroll event came
  // from an nsMacWindow, then aWindow should refer to that nsMacWindow.
  nsIWidget* widgetToScroll = aWindow->FindWidgetHit(aMouseLoc);

  // Not all scroll events for the window are over a widget.  Consider
  // the title bar.
  if (!widgetToScroll)
    return PR_FALSE;

  if (aDelta == 0) {
    // Don't need to do anything, but eat the event anyway.
    return PR_TRUE;
  }

  if (gRollupListener && gRollupWidget) {
    // Roll up the rollup widget if the scroll isn't targeted at it
    // (or one of its children) and the listener was told to do so.

    PRBool rollup = PR_FALSE;
    gRollupListener->ShouldRollupOnMouseWheelEvent(&rollup);

    if (rollup) {
      nsCOMPtr<nsIWidget> widgetOrAncestor = widgetToScroll;
      do {
        if (widgetOrAncestor == gRollupWidget) {
          rollup = PR_FALSE;
          break;
        }
      } while (widgetOrAncestor = widgetOrAncestor->GetParent());
    }

    if (rollup)
      gRollupListener->Rollup();
  }

  nsMouseScrollEvent scrollEvent(PR_TRUE, NS_MOUSE_SCROLL, widgetToScroll);

  // The direction we get from the carbon event is opposite from the way
  // mozilla looks at it.  Reverse the direction.
  scrollEvent.delta = -aDelta;

  // If the scroll event comes from a mouse that only has a scroll wheel for
  // the vertical axis, and the shift key is held down, the system presents
  // it as a horizontal scroll and doesn't clear the shift key bit from
  // aModifiers.  The Mac is supposed to scroll horizontally in such a case.
  //
  // If the scroll event comes from a mouse that can scroll both axes, the
  // system doesn't apply any of this shift-key fixery.
  scrollEvent.scrollFlags = aAxis;

  if (aIsPixels)
    scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsPixels;

  // convert window-relative (local) mouse coordinates to widget-relative
  // coords for Gecko.
  nsPoint mouseLocRelativeToWidget(aMouseLoc.h, aMouseLoc.v);
  nsRect bounds;
  widgetToScroll->GetBounds(bounds);
  nsPoint widgetOrigin(bounds.x, bounds.y);
  widgetToScroll->ConvertToDeviceCoordinates(widgetOrigin.x, widgetOrigin.y);
  mouseLocRelativeToWidget.MoveBy(-widgetOrigin.x, -widgetOrigin.y);

  scrollEvent.point.x = mouseLocRelativeToWidget.x;
  scrollEvent.point.y = mouseLocRelativeToWidget.y;
  scrollEvent.time = PR_IntervalNow();

  // Translate OS event modifiers into Gecko event modifiers
  scrollEvent.isShift   = ((aModifiers & shiftKey)   != 0);
  scrollEvent.isControl = ((aModifiers & controlKey) != 0);
  scrollEvent.isAlt     = ((aModifiers & optionKey)  != 0);
  scrollEvent.isMeta    = ((aModifiers & cmdKey)     != 0);

  nsEventStatus status;
  widgetToScroll->DispatchEvent(&scrollEvent, status);

  return nsWindow::ConvertStatus(status);
} // ScrollAxis

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMacEventHandler::UnicodeHandleUpdateInputArea ( const PRUnichar text,
long  charCount,
long  fixedLength,
TextRangeArray *  textRangeArray 
) [virtual]

Definition at line 1887 of file nsMacEventHandler.cpp.

{
#ifdef DEBUG_TSM
  printf("********************************************************************************\n");
  printf("nsMacEventHandler::UnicodeHandleUpdateInputArea size=%d fixlen=%d\n",charCount, fixedLength);
#endif
  nsresult res = NS_OK;
  long committedLen = 0;
  //------------------------------------------------------------------------------------------------
  // if we aren't in composition mode alredy, signal the backing store w/ the mode change
  //------------------------------------------------------------------------------------------------
  if (!mIMEIsComposing) {
    res = HandleStartComposition();
    NS_ASSERTION(NS_SUCCEEDED(res), "nsMacEventHandler::UnicodeHandleUpdateInputArea: HandleStartComposition failed.");
    if (NS_FAILED(res))
      goto error;
  }
  // mIMECompositionStr should be created in the HandleStartComposition
  NS_ASSERTION(mIMECompositionStr, "do not have mIMECompositionStr");
  if (nsnull == mIMECompositionStr)
  {
    res = NS_ERROR_OUT_OF_MEMORY;
    goto error;
  }

  //====================================================================================================
  // Note- It is possible that the UpdateInputArea event sent both committed text and uncommitted text
  // at the same time. The easiest way to do that is using Korean input method w/ "Enter by Character" option
  //====================================================================================================
  //  1. Handle the committed text
  //====================================================================================================
  committedLen = (fixedLength == -1) ? charCount : fixedLength;
  if (0 != committedLen)
  {
#ifdef DEBUG_TSM
    printf("Have commit text from 0 to %d\n", committedLen);
#endif
    //------------------------------------------------------------------------------------------------
    // 1.1 send textEvent to commit the text
    //------------------------------------------------------------------------------------------------
    mIMECompositionStr->Assign(text, committedLen);
#ifdef DEBUG_TSM
    printf("1.2====================================\n");
#endif
    res = HandleTextEvent(0, nsnull);
    NS_ASSERTION(NS_SUCCEEDED(res), "nsMacEventHandler::UnicodeHandleUpdateInputArea: HandleTextEvent failed.");
    if (NS_FAILED(res)) 
      goto error; 
    //------------------------------------------------------------------------------------------------
    // 1.3 send compositionEvent to end the composition
    //------------------------------------------------------------------------------------------------
    res = nsMacEventHandler::HandleEndComposition();
    NS_ASSERTION(NS_SUCCEEDED(res), "nsMacEventHandler::UnicodeHandleUpdateInputArea: HandleEndComposition failed.");
    if (NS_FAILED(res)) 
      goto error; 
  }    //  1. Handle the committed text

  //====================================================================================================
  //  2. Handle the uncommitted text
  //====================================================================================================
  if ((-1 != fixedLength) && (charCount != fixedLength))
  {  
#ifdef DEBUG_TSM
    printf("Have new uncommitted text from %d to text_size(%d)\n", committedLen, charCount);
#endif
    //------------------------------------------------------------------------------------------------
    // 2.1 send compositionEvent to start the composition
    //------------------------------------------------------------------------------------------------
    //
    // if we aren't in composition mode already, signal the backing store w/ the mode change
    //  
    if (!mIMEIsComposing) {
      res = HandleStartComposition();
      NS_ASSERTION(NS_SUCCEEDED(res), "nsMacEventHandler::UnicodeHandleUpdateInputArea: HandleStartComposition failed.");
      if (NS_FAILED(res))
        goto error; 
    }   // 2.1 send compositionEvent to start the composition
    //------------------------------------------------------------------------------------------------
    // 2.2 send textEvent for the uncommitted text
    //------------------------------------------------------------------------------------------------
    //------------------------------------------------------------------------------------------------
    // 2.2.1 make sure we have one range array
    //------------------------------------------------------------------------------------------------

    TextRangeArray rawTextRangeArray;
    TextRangeArray *rangeArray;
    if (textRangeList && textRangeList->fNumOfRanges) {
      rangeArray = textRangeList;
    } else {
      rangeArray = &rawTextRangeArray;
      rawTextRangeArray.fNumOfRanges = 1;
      rawTextRangeArray.fRange[0].fStart = committedLen * 2;
      rawTextRangeArray.fRange[0].fEnd = charCount * 2;
      rawTextRangeArray.fRange[0].fHiliteStyle = NS_TEXTRANGE_RAWINPUT;      
    }

    
#ifdef DEBUG_TSM
    printf("nsMacEventHandler::UnicodeHandleUpdateInputArea textRangeList is %s\n", textRangeList ? "NOT NULL" : "NULL");
#endif
    nsTextRangeArray xpTextRangeArray = new nsTextRange[rangeArray->fNumOfRanges];
    NS_ASSERTION(xpTextRangeArray!=NULL, "nsMacEventHandler::UnicodeHandleUpdateInputArea: xpTextRangeArray memory allocation failed.");
    if (xpTextRangeArray == NULL)
    {
      res = NS_ERROR_OUT_OF_MEMORY;
      goto error; 
    }
  
    //------------------------------------------------------------------------------------------------
    // 2.2.2 convert range array into our xp range array
    //------------------------------------------------------------------------------------------------
    //
    // the TEC offset mapping capabilities won't work here because you need to have unique, ordered offsets
    //  so instead we iterate over the range list and map each range individually.  it's probably faster than
    //  trying to do collapse all the ranges into a single offset list
    //
    PRInt32 i;
    for(i = 0; i < rangeArray->fNumOfRanges; i++) {      
      // 2.2.2.1 check each range item in NS_ASSERTION
      NS_ASSERTION(
        (NS_TEXTRANGE_CARETPOSITION==rangeArray->fRange[i].fHiliteStyle)||
        (NS_TEXTRANGE_RAWINPUT==rangeArray->fRange[i].fHiliteStyle)||
        (NS_TEXTRANGE_SELECTEDRAWTEXT==rangeArray->fRange[i].fHiliteStyle)||
        (NS_TEXTRANGE_CONVERTEDTEXT==rangeArray->fRange[i].fHiliteStyle)||
        (NS_TEXTRANGE_SELECTEDCONVERTEDTEXT==rangeArray->fRange[i].fHiliteStyle),
        "illegal range type");
      NS_ASSERTION( rangeArray->fRange[i].fStart/2 <= charCount, "illegal range");
      NS_ASSERTION( rangeArray->fRange[i].fEnd/2 <= charCount, "illegal range");

#ifdef DEBUG_TSM
      printf("nsMacEventHandler::UnicodeHandleUpdateInputArea textRangeList[%d] = (%d,%d) text_size = %d\n",i,
        rangeArray->fRange[i].fStart/2, rangeArray->fRange[i].fEnd/2, charCount);
#endif      
      // 2.2.2.6 put destinationOffset into xpTextRangeArray[i].mStartOffset 
      xpTextRangeArray[i].mRangeType = rangeArray->fRange[i].fHiliteStyle;
      xpTextRangeArray[i].mStartOffset = rangeArray->fRange[i].fStart / 2;
      xpTextRangeArray[i].mEndOffset   = rangeArray->fRange[i].fEnd / 2;

      // 2.2.2.7 Check the converted result in NS_ASSERTION
#ifdef DEBUG_TSM
      printf("nsMacEventHandler::UnicodeHandleUpdateInputArea textRangeList[%d] => type=%d (%d,%d)\n",i,
        xpTextRangeArray[i].mRangeType,
        xpTextRangeArray[i].mStartOffset, xpTextRangeArray[i].mEndOffset);
#endif      

      NS_ASSERTION((NS_TEXTRANGE_CARETPOSITION!=xpTextRangeArray[i].mRangeType) ||
             (xpTextRangeArray[i].mStartOffset == xpTextRangeArray[i].mEndOffset),
             "start != end in CaretPosition");
    }
    mIMECompositionStr->Assign(text+committedLen, charCount-committedLen);
    //------------------------------------------------------------------------------------------------
    // 2.2.4 send the text event
    //------------------------------------------------------------------------------------------------
#ifdef DEBUG_TSM
      printf("2.2.4====================================\n");
#endif      

    res = HandleTextEvent(rangeArray->fNumOfRanges,xpTextRangeArray);
    NS_ASSERTION(NS_SUCCEEDED(res), "nsMacEventHandler::UnicodeHandleUpdateInputArea: HandleTextEvent failed.");
    if (NS_FAILED(res)) 
      goto error; 
    delete [] xpTextRangeArray;
  } //  2. Handle the uncommitted text
  else if ((0==charCount) && (0==fixedLength))
  {
    // 3. Handle empty text event
    // This is needed when we input some uncommitted text, and then delete all of them
    // When the last delete come, we will got a text_size = 0 and fixedLength = 0
    // In that case, we need to send a text event to clean up the input hole....
    mIMECompositionStr->Truncate();      
#ifdef DEBUG_TSM
      printf("3.====================================\n");
#endif
    // 3.1 send the empty text event.
    res = HandleTextEvent(0, nsnull);
    NS_ASSERTION(NS_SUCCEEDED(res),"nsMacEventHandler::UnicodeHandleUpdateInputArea: HandleTextEvent failed.");
    if (NS_FAILED(res)) 
      goto error; 
    // 3.2 send an endComposition event, we need this to make sure the delete after this work properly.
    res = nsMacEventHandler::HandleEndComposition();
    NS_ASSERTION(NS_SUCCEEDED(res),"nsMacEventHandler::UnicodeHandleUpdateInputArea: HandleEndComposition failed.");
    if (NS_FAILED(res)) 
      goto error;     
  }
  
error:
  return res;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 184 of file nsMacEventHandler.h.

Definition at line 176 of file nsMacEventHandler.h.

Definition at line 181 of file nsMacEventHandler.h.

Definition at line 186 of file nsMacEventHandler.h.

Definition at line 180 of file nsMacEventHandler.h.

Definition at line 188 of file nsMacEventHandler.h.

Definition at line 187 of file nsMacEventHandler.h.

Definition at line 185 of file nsMacEventHandler.h.

Definition at line 183 of file nsMacEventHandler.h.

Definition at line 182 of file nsMacEventHandler.h.

Definition at line 189 of file nsMacEventHandler.h.

Definition at line 190 of file nsMacEventHandler.h.

Definition at line 177 of file nsMacEventHandler.h.

TSMDocumentID nsMacEventHandler::mTSMDocument [protected]

Definition at line 179 of file nsMacEventHandler.h.

Definition at line 178 of file nsMacEventHandler.h.


The documentation for this class was generated from the following files: