Beispiel #1
0
bool
nsCoreUtils::DispatchMouseEvent(uint32_t aEventType,
                                nsIPresShell *aPresShell,
                                nsIContent *aContent)
{
  nsIFrame *frame = aContent->GetPrimaryFrame();
  if (!frame)
    return false;

  // Compute x and y coordinates.
  nsPoint point;
  nsCOMPtr<nsIWidget> widget = frame->GetNearestWidget(point);
  if (!widget)
    return false;

  nsSize size = frame->GetSize();

  nsPresContext* presContext = aPresShell->GetPresContext();

  int32_t x = presContext->AppUnitsToDevPixels(point.x + size.width / 2);
  int32_t y = presContext->AppUnitsToDevPixels(point.y + size.height / 2);

  // Fire mouse event.
  DispatchMouseEvent(aEventType, x, y, aContent, frame, aPresShell, widget);
  return true;
}
Beispiel #2
0
void InputManager::DispatchEvents()
{	
	EEvent e; 
	for (uint32 i = 0; i < m_events.Size(); i++) {
		e = m_events[i]->GetType(); 
		if (e == ON_MOUSE_EVENT) {
			DispatchMouseEvent(m_events[i]);
		}
		else if (e == ON_KEYBOARD_EVENT) {
			DispatchKeyboardEvent(m_events[i]);
		}
		RemoveEvent(m_events[i]);
	}
}
void
GeckoTouchDispatcher::DispatchTouchEvent(MultiTouchInput& aMultiTouch)
{
  if ((aMultiTouch.mType == MultiTouchInput::MULTITOUCH_END ||
       aMultiTouch.mType == MultiTouchInput::MULTITOUCH_CANCEL) &&
      aMultiTouch.mTouches.Length() == 1) {
    MutexAutoLock lock(mTouchQueueLock);
    mTouchMoveEvents.clear();
  } else if (aMultiTouch.mType == MultiTouchInput::MULTITOUCH_START &&
             aMultiTouch.mTouches.Length() == 1) {
    mTouchEventsFiltered = IsExpired(aMultiTouch);
  }

  if (mTouchEventsFiltered) {
    return;
  }

  bool captured = false;
  WidgetTouchEvent event = aMultiTouch.ToWidgetTouchEvent(nullptr);
  nsEventStatus status = nsWindow::DispatchInputEvent(event, &captured);

  if (mEnabledUniformityInfo) {
    const char* touchAction = "Invalid";
    switch (aMultiTouch.mType) {
      case MultiTouchInput::MULTITOUCH_START:
        touchAction = "Touch_Event_Down";
        break;
      case MultiTouchInput::MULTITOUCH_MOVE:
        touchAction = "Touch_Event_Move";
        break;
      case MultiTouchInput::MULTITOUCH_END:
      case MultiTouchInput::MULTITOUCH_CANCEL:
        touchAction = "Touch_Event_Up";
        break;
    }

    const SingleTouchData& firstTouch = aMultiTouch.mTouches[0];
    const ScreenIntPoint& touchPoint = firstTouch.mScreenPoint;

    LOG("UniformityInfo %s %llu %d %d", touchAction, systemTime(SYSTEM_TIME_MONOTONIC),
        touchPoint.x, touchPoint.y);
  }

  if (!captured && (aMultiTouch.mTouches.Length() == 1)) {
    bool forwardToChildren = status != nsEventStatus_eConsumeNoDefault;
    DispatchMouseEvent(aMultiTouch, forwardToChildren);
  }
}
Beispiel #4
0
void
nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
                                int32_t aRowIndex, nsITreeColumn *aColumn,
                                const nsCString& aPseudoElt)
{
  nsCOMPtr<nsIDOMElement> tcElm;
  aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
  if (!tcElm)
    return;

  nsCOMPtr<nsIContent> tcContent(do_QueryInterface(tcElm));
  nsIDocument *document = tcContent->GetCurrentDoc();
  if (!document)
    return;

  nsIPresShell *presShell = nullptr;
  presShell = document->GetShell();
  if (!presShell)
    return;

  // Ensure row is visible.
  aTreeBoxObj->EnsureRowIsVisible(aRowIndex);

  // Calculate x and y coordinates.
  int32_t x = 0, y = 0, width = 0, height = 0;
  nsresult rv = aTreeBoxObj->GetCoordsForCellItem(aRowIndex, aColumn,
                                                  aPseudoElt,
                                                  &x, &y, &width, &height);
  if (NS_FAILED(rv))
    return;

  nsCOMPtr<nsIDOMXULElement> tcXULElm(do_QueryInterface(tcElm));
  nsCOMPtr<nsIBoxObject> tcBoxObj;
  tcXULElm->GetBoxObject(getter_AddRefs(tcBoxObj));

  int32_t tcX = 0;
  tcBoxObj->GetX(&tcX);

  int32_t tcY = 0;
  tcBoxObj->GetY(&tcY);

  // Dispatch mouse events.
  nsIFrame* tcFrame = tcContent->GetPrimaryFrame();
  nsIFrame* rootFrame = presShell->GetRootFrame();

  nsPoint offset;
  nsIWidget *rootWidget =
    rootFrame->GetViewExternal()->GetNearestWidget(&offset);

  nsPresContext* presContext = presShell->GetPresContext();

  int32_t cnvdX = presContext->CSSPixelsToDevPixels(tcX + x + 1) +
    presContext->AppUnitsToDevPixels(offset.x);
  int32_t cnvdY = presContext->CSSPixelsToDevPixels(tcY + y + 1) +
    presContext->AppUnitsToDevPixels(offset.y);

  DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, cnvdX, cnvdY,
                     tcContent, tcFrame, presShell, rootWidget);

  DispatchMouseEvent(NS_MOUSE_BUTTON_UP, cnvdX, cnvdY,
                     tcContent, tcFrame, presShell, rootWidget);
}
Beispiel #5
0
// used only once
inline PRBool nsWidget::HandleEvent( PtWidget_t *widget, PtCallbackInfo_t* aCbInfo ) {
    PRBool  result = PR_TRUE; // call the default nsWindow proc
    PhEvent_t* event = aCbInfo->event;
    static int prevx=-1, prevy=-1, left_button_down, kwww_outbound_valid;

    if (event->processing_flags & Ph_CONSUMED) return PR_TRUE;

    switch ( event->type ) {

    case Ph_EV_PTR_MOTION_NOBUTTON:
    {
        PhPointerEvent_t* ptrev = (PhPointerEvent_t*) PhGetData( event );
        nsMouseEvent theMouseEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);

        if( ptrev ) {

            if( ptrev->flags & Ph_PTR_FLAG_Z_ONLY ) break; // sometimes z presses come out of nowhere */

///* ATENTIE */ printf( "Ph_EV_PTR_MOTION_NOBUTTON (%d %d)\n", ptrev->pos.x, ptrev->pos.y );

            ScreenToWidgetPos( ptrev->pos );
            InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_MOVE );
            result = DispatchMouseEvent(theMouseEvent);
        }
    }
    break;

    case Ph_EV_BUT_PRESS:
    {

        PhPointerEvent_t* ptrev = (PhPointerEvent_t*) PhGetData( event );
        nsMouseEvent theMouseEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);

        /* there should be no reason to do this - mozilla should figure out how to call SetFocus */
        /* this though fixes the problem with the plugins capturing the focus */
        PtWidget_t *disjoint = PtFindDisjoint( widget );
        if( PtWidgetIsClassMember( disjoint, PtServer ) || //mozserver
                PtWidgetIsClassMember( disjoint, PtContainer ) ) //TestPhEmbed
            PtContainerGiveFocus( widget, aCbInfo->event );

        if( ptrev ) {
            prevx = ptrev->pos.x;
            prevy = ptrev->pos.y;
            ScreenToWidgetPos( ptrev->pos );

            if( ptrev->buttons & Ph_BUTTON_SELECT ) { // Normally the left mouse button
                InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_LEFT_BUTTON_DOWN );
                left_button_down = 1;
            } else if( ptrev->buttons & Ph_BUTTON_MENU ) // the right button
                InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_RIGHT_BUTTON_DOWN );
            else // middle button
                InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_MIDDLE_BUTTON_DOWN );

            //printf("*** Button down\n");
            result = DispatchMouseEvent(theMouseEvent);

            // if we're a right-button-down we're trying to popup a context menu. send that event to gecko also
            if( ptrev->buttons & Ph_BUTTON_MENU ) {
                nsMouseEvent contextMenuEvent(PR_TRUE, 0, nsnull,
                                              nsMouseEvent::eReal);
                InitMouseEvent( ptrev, this, contextMenuEvent, NS_CONTEXTMENU );
                result = DispatchMouseEvent( contextMenuEvent );
            }
        }

    }
    break;

    case Ph_EV_BUT_RELEASE:
    {
        PhPointerEvent_t* ptrev = (PhPointerEvent_t*) PhGetData( event );
        nsMouseEvent theMouseEvent(PR_TRUE, 0, nsnull,
                                   nsMouseEvent::eReal);

        // Update the current input group for clipboard mouse events
        // (mozilla only). Note that for mozserver the mouse based
        // (eg. Edit->Copy/Paste menu) events don't come through here.
        // They are sent by the voyager client app via libPtWeb.so to
        // do_command() in mozserver.cpp.
        if (sClipboard)
            sClipboard->SetInputGroup(event->input_group);

        if (event->subtype==Ph_EV_RELEASE_REAL || event->subtype==Ph_EV_RELEASE_PHANTOM) {
            if (ptrev) {
                ScreenToWidgetPos( ptrev->pos );
                if ( ptrev->buttons & Ph_BUTTON_SELECT ) { // Normally the left mouse button
                    InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_LEFT_BUTTON_UP );
                    kwww_outbound_valid = 0;
                    //
                    // To be clean, let's not send multiple left button up
                    // events.
                    //
                    if (!left_button_down)
                        break; //case
                    left_button_down = 0;
                } else if( ptrev->buttons & Ph_BUTTON_MENU ) // the right button
                    InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_RIGHT_BUTTON_UP );
                else // middle button
                    InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_MIDDLE_BUTTON_UP );

                //printf("*** Button up %s\n", event->subtype==Ph_EV_RELEASE_PHANTOM ? "(phantom)" : "");
                result = DispatchMouseEvent(theMouseEvent);
            }
        }
        else if (event->subtype==Ph_EV_RELEASE_OUTBOUND) {
            PhRect_t rect = {{0,0},{0,0}};
            PhRect_t boundary = {{-10000,-10000},{10000,10000}};

            //printf("*** OUTBOUND\n");
            if (__progname && strcmp(__progname, "kwww") == 0) {
                //
                // In kscope we only use dragging to scroll the view. So
                // we don't want Mozilla to do any special drag processing,
                // and fake this out by immediately doing a left-button-up.
                // We do it at (999999,999999) so any control or link under
                // the pointer doesn't get activated.
                //
                ptrev->pos.x = ptrev->pos.y = 999999;
                InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_LEFT_BUTTON_UP );
                result = DispatchMouseEvent(theMouseEvent);
                InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_MOVE );
                result = DispatchMouseEvent(theMouseEvent);
                left_button_down = 0;
                kwww_outbound_valid = 1;
                //
                // In case we activated a combo box, do another down/up
                // Sending an Esc key also works. Which is better?
                // The mouse button method may prevent drag initiation
                // within (multiline?) input fields.
                //
#if 0
                InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_LEFT_BUTTON_DOWN );
                result = DispatchMouseEvent(theMouseEvent);
                InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_LEFT_BUTTON_UP );
                result = DispatchMouseEvent(theMouseEvent);
#else
                PhKeyEvent_t kev;
                memset( &kev, 0, sizeof(kev) );
                kev.key_cap = kev.key_sym = Pk_Escape;
                kev.key_flags = Pk_KF_Key_Down | Pk_KF_Cap_Valid | Pk_KF_Sym_Valid;
                DispatchKeyEvent( &kev, 1 );
                memset( &kev, 0, sizeof(kev) );
                kev.key_cap = Pk_Escape;
                kev.key_flags = Pk_KF_Cap_Valid;
                DispatchKeyEvent( &kev, 1 );
#endif
            }

            PhInitDrag( PtWidgetRid(mWidget), ( Ph_DRAG_KEY_MOTION | Ph_DRAG_TRACK | Ph_TRACK_DRAG),&rect, &boundary, aCbInfo->event->input_group , NULL, NULL, NULL, NULL, NULL);
        }
    }
    break;

    case Ph_EV_PTR_MOTION_BUTTON:
    {
        PhPointerEvent_t* ptrev = (PhPointerEvent_t*) PhGetData( event );
        nsMouseEvent theMouseEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);

        if( ptrev ) {

            if( ptrev->flags & Ph_PTR_FLAG_Z_ONLY ) break; // sometimes z presses come out of nowhere */

#ifdef PHOTON_DND
            if( sDragService ) {
                nsDragService *d;
                nsIDragService *s = sDragService;
                d = ( nsDragService * )s;
                d->SetNativeDndData( widget, event );
            }
#endif

            if (!__progname || strcmp(__progname, "kwww") != 0) {
                //
                // We don't send these events in kscope. Dragging is devoted to
                // scrolling.
                //
                ScreenToWidgetPos( ptrev->pos );
                InitMouseEvent(ptrev, this, theMouseEvent, NS_MOUSE_MOVE );
                result = DispatchMouseEvent(theMouseEvent);
            }
        }
    }
    break;

    case Ph_EV_KEY:
        // Update the current input group for clipboard key events. This
        // covers both mozserver and mozilla.
        if (sClipboard)
            sClipboard->SetInputGroup(event->input_group);
        result = DispatchKeyEvent( (PhKeyEvent_t*) PhGetData( event ), 0 );
        break;

    case Ph_EV_DRAG:
    {
        nsMouseEvent theMouseEvent(PR_TRUE, 0, nsnull, nsMouseEvent::eReal);

        switch(event->subtype) {
            static int is_kwww=-1;

        case Ph_EV_DRAG_COMPLETE: {
            nsMouseEvent theMouseEvent(PR_TRUE, 0, nsnull,
                                       nsMouseEvent::eReal);
            PhPointerEvent_t* ptrev2 = (PhPointerEvent_t*) PhGetData( event );
            //printf("*** Drag complete\n");
            if (is_kwww) {
                // Already did the button up
                kwww_outbound_valid = 0;
                prevx = prevy = -1;
            } else {
                ScreenToWidgetPos( ptrev2->pos );
                InitMouseEvent(ptrev2, this, theMouseEvent, NS_MOUSE_LEFT_BUTTON_UP );
                result = DispatchMouseEvent(theMouseEvent);
                left_button_down = 0;
            }
        }
        break;
        case Ph_EV_DRAG_MOTION_EVENT: {
            PhPointerEvent_t* ptrev2 = (PhPointerEvent_t*) PhGetData( event );
            //printf("*** Drag motion\n");
            if (is_kwww == -1) {
                is_kwww = 0;
                if (__progname && strcmp(__progname, "kwww") == 0)
                    is_kwww = 1;
            }

            if (is_kwww) {
                nsIWidget *nsw = this;
                nsIWidget *top_widget = nsw;

                if (!kwww_outbound_valid) {
                    struct dragevent {
                        PhEvent_t hdr;
                        PhDragEvent_t drag;
                    } ev;

                    //
                    // If the user does a drag where he releases the left mouse
                    // button almost right away, then we will start getting
                    // drag events even though the mouse button is not pressed!
                    // Work around this Photon bug by cancelling the drag
                    // ourselves. In 6.4.0 we can use PhCancelDrag() to do this.
                    //
                    //printf("*** CANCELLING DRAG!\n");
                    memset( &ev, 0, sizeof(ev) );
                    ev.hdr.type = Ph_EV_DRAG;
                    ev.hdr.emitter.rid = Ph_DEV_RID;
                    ev.hdr.flags = Ph_EVENT_INCLUSIVE | Ph_EMIT_TOWARD;
                    ev.hdr.data_len = sizeof( ev.drag );
                    ev.hdr.subtype = Ph_EV_DRAG_COMPLETE;
                    ev.hdr.input_group = aCbInfo->event->input_group;
                    ev.drag.rid = PtWidgetRid(mWidget);
                    ev.drag.flags = 0;
                    PhEmit( &ev.hdr, NULL, &ev.drag );
                    break; //case
                }

                while (nsw) {
                    top_widget = nsw;
                    nsw = nsw->GetParent();
                }
try_again:
                nsIView *view = nsToolkit::GetViewFor(top_widget);
                if (view) {
                    nsIViewManager* vm = view->GetViewManager();
                    if (vm) {
                        nsIScrollableView* scrollView = nsnull;
                        vm->GetRootScrollableView(&scrollView);
                        if (scrollView) {
                            if (prevx != -1 || prevy != -1) {
                                //
                                // The -1 check is to handle prevx and prevy not set
                                // to the button press location, which happens when
                                // you click on flash.
                                //
                                nsresult rc = ((nsIScrollableView_MOZILLA_1_8_BRANCH*)scrollView)->ScrollByPixels(prevx - ptrev2->pos.x, prevy - ptrev2->pos.y);
                                //printf("*** rc %d from ScrollByPixels\n");
                            }
                        } else if (top_widget != this) {
                            //
                            // There is no scrollable view for the top level widget.
                            // See if there is one for the original widget.
                            //
                            top_widget = this;
                            goto try_again;
                        }
                    }
                }
                prevx = ptrev2->pos.x;
                prevy = ptrev2->pos.y;
            } else {
                ScreenToWidgetPos( ptrev2->pos );
                InitMouseEvent(ptrev2, this, theMouseEvent, NS_MOUSE_MOVE );
                result = DispatchMouseEvent(theMouseEvent);
            }
        }
        break;
        }
    }
    break;

    case Ph_EV_BOUNDARY:
        PRUint32 evtype;

        switch( event->subtype ) {
        case Ph_EV_PTR_ENTER:
        case Ph_EV_PTR_ENTER_FROM_CHILD:
            evtype = NS_MOUSE_ENTER;
            break;
        case Ph_EV_PTR_LEAVE_TO_CHILD:
        case Ph_EV_PTR_LEAVE:
            evtype = NS_MOUSE_EXIT;
            break;
        default:
            evtype = 0;
            break;
        }

        if( evtype != 0 ) {
            PhPointerEvent_t* ptrev = (PhPointerEvent_t*) PhGetData( event );
            nsMouseEvent theMouseEvent(PR_TRUE, 0, nsnull,
                                       nsMouseEvent::eReal);
            ScreenToWidgetPos( ptrev->pos );
            InitMouseEvent( ptrev, this, theMouseEvent, evtype );
            result = DispatchMouseEvent( theMouseEvent );
        }
        break;
    }

    return result;
}