Esempio n. 1
0
void
MouseEvent::InitMouseEvent(const nsAString& aType,
                           bool aCanBubble,
                           bool aCancelable,
                           nsGlobalWindow* aView,
                           int32_t aDetail,
                           int32_t aScreenX,
                           int32_t aScreenY,
                           int32_t aClientX,
                           int32_t aClientY,
                           int16_t aButton,
                           EventTarget* aRelatedTarget,
                           const nsAString& aModifiersList)
{
  NS_ENSURE_TRUE_VOID(!mEvent->mFlags.mIsBeingDispatched);

  Modifiers modifiers = ComputeModifierState(aModifiersList);

  InitMouseEvent(aType, aCanBubble, aCancelable, aView, aDetail,
                 aScreenX, aScreenY, aClientX, aClientY,
                 (modifiers & MODIFIER_CONTROL) != 0,
                 (modifiers & MODIFIER_ALT) != 0,
                 (modifiers & MODIFIER_SHIFT) != 0,
                 (modifiers & MODIFIER_META) != 0,
                 aButton, aRelatedTarget);

  switch(mEvent->mClass) {
    case eMouseEventClass:
    case eMouseScrollEventClass:
    case eWheelEventClass:
    case eDragEventClass:
    case ePointerEventClass:
    case eSimpleGestureEventClass:
      mEvent->AsInputEvent()->mModifiers = modifiers;
      return;
    default:
      MOZ_CRASH("There is no space to store the modifiers");
  }
}
Esempio n. 2
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;
}