예제 #1
0
void fgSpaceballHandleXEvent(const XEvent *xev)
{
    spnav_event sev;

    if(!sball_initialized) {
        fgInitialiseSpaceball();
        if(!sball_initialized) {
            return;
        }
    }

    if(spnav_x11_event(xev, &sev)) {
        switch(sev.type) {
        case SPNAV_EVENT_MOTION:
            if(sev.motion.x | sev.motion.y | sev.motion.z) {
                INVOKE_WCB(*spnav_win, SpaceMotion, (sev.motion.x, sev.motion.y, sev.motion.z));
            }
            if(sev.motion.rx | sev.motion.ry | sev.motion.rz) {
                INVOKE_WCB(*spnav_win, SpaceRotation, (sev.motion.rx, sev.motion.ry, sev.motion.rz));
            }
            spnav_remove_events(SPNAV_EVENT_MOTION);
            break;

        case SPNAV_EVENT_BUTTON:
            INVOKE_WCB(*spnav_win, SpaceButton, (sev.button.bnum, sev.button.press ? GLUT_DOWN : GLUT_UP));
            break;

        default:
            break;
        }
    }
}
예제 #2
0
int fgIsSpaceballXEvent(const XEvent *xev)
{
    spnav_event sev;

    if(!sball_initialized) {
        fgInitialiseSpaceball();
        if(!sball_initialized) {
            return 0;
        }
    }

    return spnav_x11_event(xev, &sev);
}
bool Gui::GUIApplicationNativeEventAware::x11EventFilter(XEvent *event)
{
#ifdef SPNAV_FOUND
    spnav_event navEvent;
    if (!spnav_x11_event(event, &navEvent))
        return false;

    QWidget *currentWidget = this->focusWidget();
    if (!currentWidget)
        currentWidget = mainWindow;

    if (navEvent.type == SPNAV_EVENT_MOTION)
    {
        motionDataArray[0] = navEvent.motion.x;
        motionDataArray[1] = navEvent.motion.y;
        motionDataArray[2] = navEvent.motion.z;
        motionDataArray[3] = navEvent.motion.rx;
        motionDataArray[4] = navEvent.motion.ry;
        motionDataArray[5] = navEvent.motion.rz;

        if (!setOSIndependentMotionData()) return false;
        importSettings();

        Spaceball::MotionEvent *motionEvent = new Spaceball::MotionEvent();

        motionEvent->setTranslations(motionDataArray[0], motionDataArray[1], motionDataArray[2]);
        motionEvent->setRotations(motionDataArray[3], motionDataArray[4], motionDataArray[5]);

        this->postEvent(currentWidget, motionEvent);
        return true;
    }

    if (navEvent.type == SPNAV_EVENT_BUTTON)
    {
        Spaceball::ButtonEvent *buttonEvent = new Spaceball::ButtonEvent();
        buttonEvent->setButtonNumber(navEvent.button.bnum);
        if (navEvent.button.press)
            buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED);
        else
            buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED);
        this->postEvent(currentWidget, buttonEvent);
        return true;
    }

    Base::Console().Log("Unknown spaceball event\n");
    return true;
#else
    return false;
#endif // SPNAV_FOUND
}
예제 #4
0
int fgIsSpaceballXEvent(const XEvent *xev)
{
    spnav_event sev;

    if(spnav_win != fgStructure.CurrentWindow) {
        /* this will also initialize spaceball if needed (first call) */
        fgSpaceballSetWindow(fgStructure.CurrentWindow);
    }

    if(sball_initialized != 1) {
        return 0;
    }

    return spnav_x11_event(xev, &sev);
}
예제 #5
0
파일: spnav.c 프로젝트: amaldo/Omni_base
int spnav_wait_event(spnav_event *event)
{
#ifdef USE_X11
	if(dpy) {
		for(;;) {
			XEvent xev;
			XNextEvent(dpy, &xev);

			if(spnav_x11_event(&xev, event) > 0) {
				return event->type;
			}
		}
	}
#endif

	if(sock) {
		if(read_event(sock, event) > 0) {
			return event->type;
		}
	}
	return 0;
}
예제 #6
0
파일: spnav.c 프로젝트: amaldo/Omni_base
int spnav_poll_event(spnav_event *event)
{
#ifdef USE_X11
	if(dpy) {
		if(XPending(dpy)) {
			XEvent xev;
			XNextEvent(dpy, &xev);

			return spnav_x11_event(&xev, event);
		}
		return 0;
	}
#endif

	if(sock) {
		if(event_pending(sock)) {
			if(read_event(sock, event) > 0) {
				return event->type;
			}
		}
	}
	return 0;
}
예제 #7
0
void EventHandler::_processEvent( WindowEvent& event )
{
    LB_TS_THREAD( _thread );

    XEvent& xEvent = event.xEvent;
    XID drawable = xEvent.xany.window;

    if( _window->getXDrawable() != drawable )
        return;

    switch( xEvent.type )
    {
        case Expose:
            if( xEvent.xexpose.count ) // Only report last expose event
                return;

            event.type = Event::WINDOW_EXPOSE;
            break;

        case ConfigureNotify:
            event.type = Event::WINDOW_RESIZE;
            _getWindowSize( xEvent.xany.display, drawable, event.resize );
            break;

        case UnmapNotify:
            event.type = Event::WINDOW_HIDE;
            _getWindowSize( xEvent.xany.display, drawable, event.resize );
            break;

        case MapNotify:
            event.type = Event::WINDOW_SHOW;
            _getWindowSize( xEvent.xany.display, drawable, event.resize );
            break;

        case ClientMessage:
        {
#ifdef EQUALIZER_USE_MAGELLAN_GLX
            spnav_event spev;

            /* spacenav event */
            if( spnav_x11_event( &xEvent, &spev ))
            {
                switch( spev.type )
                {
                  case SPNAV_EVENT_MOTION:
                    event.type = Event::MAGELLAN_AXIS;
                    event.magellan.xAxis =  spev.motion.x;
                    event.magellan.yAxis =  spev.motion.y;
                    event.magellan.zAxis = -spev.motion.z;
                    event.magellan.xRotation = -spev.motion.rx;
                    event.magellan.yRotation = -spev.motion.ry;
                    event.magellan.zRotation =  spev.motion.rz;
                    break;

                  case SPNAV_EVENT_BUTTON:
                    event.type = Event::MAGELLAN_BUTTON;
                    event.magellan.buttons = spev.button.press;
                    event.magellan.button = spev.button.bnum;
                    break;

                  default:
                    LBUNIMPLEMENTED;
                    return;
                }

                /* remove any other queued motion events */
                //? spnav_remove_events( SPNAV_EVENT_MOTION );
                break;
            }
 #endif

            Atom deleteAtom = XInternAtom( xEvent.xany.display,
                                           "WM_DELETE_WINDOW", False );

            if( static_cast<Atom>( xEvent.xclient.data.l[0] ) != deleteAtom )
                return; // not a delete message, ignore.
        }
        // else: delete message, fall through
        case DestroyNotify:
            event.type = Event::WINDOW_CLOSE;
            break;

        case MotionNotify:
            event.type = Event::WINDOW_POINTER_MOTION;
            event.pointerMotion.x = xEvent.xmotion.x;
            event.pointerMotion.y = xEvent.xmotion.y;
            event.pointerMotion.buttons = _getButtonState( xEvent );
            event.pointerMotion.button  = PTR_BUTTON_NONE;

            _computePointerDelta( event );
            break;

        case ButtonPress:
            event.type = Event::WINDOW_POINTER_BUTTON_PRESS;
            event.pointerButtonPress.x = xEvent.xbutton.x;
            event.pointerButtonPress.y = xEvent.xbutton.y;
            event.pointerButtonPress.buttons = _getButtonState( xEvent );
            event.pointerButtonPress.button  = _getButtonAction( xEvent );

            // Translate wheel events
            switch( event.pointerButtonPress.button )
            {
              case PTR_BUTTON4: event.pointerWheel.yAxis = 1; break;
              case PTR_BUTTON5: event.pointerWheel.yAxis = -1; break;
              case PTR_BUTTON6: event.pointerWheel.xAxis = 1; break;
              case PTR_BUTTON7: event.pointerWheel.xAxis = -1; break;
            }
            switch( event.pointerButtonPress.button )
            {
              case PTR_BUTTON4:
              case PTR_BUTTON5:
              case PTR_BUTTON6:
              case PTR_BUTTON7:
                event.type = Event::WINDOW_POINTER_WHEEL;
                event.pointerWheel.button = PTR_BUTTON_NONE;
            }

            _computePointerDelta( event );
            break;

        case ButtonRelease:
            event.type = Event::WINDOW_POINTER_BUTTON_RELEASE;
            event.pointerButtonRelease.x = xEvent.xbutton.x;
            event.pointerButtonRelease.y = xEvent.xbutton.y;
            event.pointerButtonRelease.buttons = _getButtonState( xEvent );
            event.pointerButtonRelease.button  = _getButtonAction( xEvent);

            _computePointerDelta( event );
            break;

        case KeyPress:
            event.type = Event::KEY_PRESS;
            event.keyPress.key = _getKey( xEvent );
            break;

        case KeyRelease:
            event.type = Event::KEY_RELEASE;
            event.keyPress.key = _getKey( xEvent );
            break;

        case ReparentNotify:
        case VisibilityNotify:
            event.type = Event::UNKNOWN;
            LBVERB << "Ignored X event, type " << xEvent.type << std::endl;
            break;

        default:
            event.type = Event::UNKNOWN;
            LBWARN << "Unhandled X event, type " << xEvent.type << std::endl;
            break;
    }

    _window->processEvent( event );
}
예제 #8
0
bool EventHandler::_processEvent( const XEvent& event )
{
    LB_TS_THREAD( _thread );

    XID drawable = event.xany.window;
    if( _window->getXDrawable() != drawable )
        return false;

    switch( event.type )
    {
    case Expose:
        if( event.xexpose.count ) // Only report last expose event
            return true;

        return _window->processEvent( EVENT_WINDOW_EXPOSE, event );

    case ConfigureNotify:
    {
        SizeEvent sizeEvent;
        _getWindowSize( event.xany.display, drawable, sizeEvent );
        return _window->processEvent( EVENT_WINDOW_RESIZE, event, sizeEvent );
    }

    case UnmapNotify:
    {
        SizeEvent sizeEvent;
        _getWindowSize( event.xany.display, drawable, sizeEvent );
        return _window->processEvent( EVENT_WINDOW_HIDE, event, sizeEvent );
    }

    case MapNotify:
    {
        SizeEvent sizeEvent;
        _getWindowSize( event.xany.display, drawable, sizeEvent );
        return _window->processEvent( EVENT_WINDOW_SHOW, event, sizeEvent );
    }

    case ClientMessage:
    {
#ifdef EQUALIZER_USE_MAGELLAN_GLX
        spnav_event spev;

        if( spnav_x11_event( &event, &spev )) // spacenav event
        {
            switch( spev.type )
            {
            case SPNAV_EVENT_MOTION:
            {
                AxisEvent axisEvent;
                axisEvent.xAxis =  spev.motion.x;
                axisEvent.yAxis =  spev.motion.y;
                axisEvent.zAxis = -spev.motion.z;
                axisEvent.xRotation = -spev.motion.rx;
                axisEvent.yRotation = -spev.motion.ry;
                axisEvent.zRotation =  spev.motion.rz;
                return _window->processEvent( event, axisEvent );
            }

            case SPNAV_EVENT_BUTTON:
            {
                ButtonEvent buttonEvent;
                buttonEvent.buttons = spev.button.press;
                buttonEvent.button = spev.button.bnum;
                return _window->processEvent( event, buttonEvent );
            }

            default:
                LBUNIMPLEMENTED;
                return false;
            }

            break;
        }
 #endif

        Atom deleteAtom = XInternAtom( event.xany.display, "WM_DELETE_WINDOW",
                                       False );

        if( static_cast<Atom>( event.xclient.data.l[0] ) != deleteAtom )
            return false; // not a delete message, ignore.
    }
    // else: delete message, fall through

    case DestroyNotify:
        return _window->processEvent( EVENT_WINDOW_CLOSE, event );

    case MotionNotify:
    {
        PointerEvent pointerEvent;
        pointerEvent.x = event.xmotion.x;
        pointerEvent.y = event.xmotion.y;
        pointerEvent.buttons = _getButtonState( event );
        pointerEvent.button  = PTR_BUTTON_NONE;
        pointerEvent.modifiers = _getKeyModifiers( event.xbutton.state );
        _computePointerDelta( EVENT_WINDOW_POINTER_MOTION, pointerEvent );


        return _window->processEvent( EVENT_WINDOW_POINTER_MOTION, event,
                                      pointerEvent );
    }

    case ButtonPress:
    {
        PointerEvent pointerEvent;
        pointerEvent.x = event.xbutton.x;
        pointerEvent.y = event.xbutton.y;
        pointerEvent.buttons = _getButtonState( event );
        pointerEvent.button  = _getButtonAction( event );
        pointerEvent.modifiers = _getKeyModifiers( event.xbutton.state );

        switch( pointerEvent.button ) // Translate wheel events
        {
        case PTR_BUTTON4: pointerEvent.yAxis = 1; break;
        case PTR_BUTTON5: pointerEvent.yAxis = -1; break;
        case PTR_BUTTON6: pointerEvent.xAxis = 1; break;
        case PTR_BUTTON7: pointerEvent.xAxis = -1; break;
        }

        switch( pointerEvent.button )
        {
        case PTR_BUTTON4:
        case PTR_BUTTON5:
        case PTR_BUTTON6:
        case PTR_BUTTON7:
            pointerEvent.button = PTR_BUTTON_NONE;
            _computePointerDelta( EVENT_WINDOW_POINTER_WHEEL, pointerEvent );
            return _window->processEvent( EVENT_WINDOW_POINTER_WHEEL, event,
                                          pointerEvent );
        }

        _computePointerDelta( EVENT_WINDOW_POINTER_BUTTON_PRESS, pointerEvent );
        return _window->processEvent( EVENT_WINDOW_POINTER_BUTTON_PRESS, event,
                                      pointerEvent );
    }

    case ButtonRelease:
    {
        PointerEvent pointerEvent;
        pointerEvent.x = event.xbutton.x;
        pointerEvent.y = event.xbutton.y;
        pointerEvent.buttons = _getButtonState( event );
        pointerEvent.button  = _getButtonAction( event);
        pointerEvent.modifiers = _getKeyModifiers( event.xbutton.state );

        _computePointerDelta( EVENT_WINDOW_POINTER_BUTTON_RELEASE,
                              pointerEvent );
        return _window->processEvent( EVENT_WINDOW_POINTER_BUTTON_RELEASE,
                                      event, pointerEvent );
    }

    case KeyPress:
    {
        KeyEvent keyEvent;
        keyEvent.key = _getKey( event );
        keyEvent.modifiers = _getKeyModifiers( event.xkey.state );
        return _window->processEvent( EVENT_KEY_PRESS, event, keyEvent );
    }

    case KeyRelease:
    {
        KeyEvent keyEvent;
        keyEvent.key = _getKey( event );
        keyEvent.modifiers = _getKeyModifiers( event.xkey.state );
        return _window->processEvent( EVENT_KEY_RELEASE, event, keyEvent );
    }

    default:
        LBWARN << "Unhandled X event, type " << event.type << std::endl;
        // no break;
    case ReparentNotify:
    case VisibilityNotify:
        return _window->processEvent( EVENT_UNKNOWN, event );
    }
}
bool Gui::GUIApplicationNativeEventAware::x11EventFilter(XEvent *event)
{
#ifdef SPNAV_FOUND
    /*
    First we check if we have a motion flush event:
    - If there are unprocessed motion events we are in a flooding situation.
      In that case we wait with generating a Spaceball event.
    - A motion event counter of 0 indicates that FreeCAD is ready to process
      the event. A Spaceball event, using the saved motion data, is posted.
    */
    static Display* display = QX11Info::display();
    static Atom motion_flush_event = XInternAtom(display, "FCMotionFlushEvent", false);
    static int nMotionEvents = 0;

    QWidget *currentWidget = this->focusWidget();
    if (!currentWidget)
        currentWidget = mainWindow;

    if (event->type == ClientMessage)
    {
        Atom message_type = event->xclient.message_type;
        
        if (message_type == motion_flush_event)
        {
            nMotionEvents--;
            if (nMotionEvents == 0)
            {
                importSettings();
                
                Spaceball::MotionEvent *motionEvent = new Spaceball::MotionEvent();
                
                motionEvent->setTranslations(motionDataArray[0], motionDataArray[1], motionDataArray[2]);
                motionEvent->setRotations(motionDataArray[3], motionDataArray[4], motionDataArray[5]);

                this->postEvent(currentWidget, motionEvent);
            }
            
            return true;
        } // XEvent: motion_flush_event
    } // XEvent: ClientMessage

    /*
    From here on we deal with spacenav events only:
    - motion: The event data is saved and a self addressed flush event
              is sent through the window system (XEvent). 
              In the case of an event flooding, the motion data is added up.
    - button: A Spaceball event is posted (QInputEvent).
    */
    spnav_event navEvent;
    if (!spnav_x11_event(event, &navEvent))
        return false;

    if (navEvent.type == SPNAV_EVENT_MOTION)
    {
        /*
        If the motion data of the preceding event has not been processed
        through posting an Spaceball event (flooding situation), 
        the motion data provided by the incoming event is added to the saved data. 
        */
    	int dx, dy, dz, drx, dry, drz;

        if (nMotionEvents == 0)
        {
            dx = 0;
            dy = 0;
            dz = 0;
            drx = 0;
            dry = 0;
            drz = 0;
        }
        else
        {
            dx = motionDataArray[0];
            dy = motionDataArray[1];
            dz = motionDataArray[2];
            drx = motionDataArray[3];
            dry = motionDataArray[4];
            drz = motionDataArray[5];
        }
        
        motionDataArray[0] = navEvent.motion.x;
        motionDataArray[1] = navEvent.motion.y;
        motionDataArray[2] = navEvent.motion.z;
        motionDataArray[3] = navEvent.motion.rx;
        motionDataArray[4] = navEvent.motion.ry;
        motionDataArray[5] = navEvent.motion.rz;

        if (!setOSIndependentMotionData()) return false;
        
        motionDataArray[0] += dx;
        motionDataArray[1] += dy;
        motionDataArray[2] += dz;
        motionDataArray[3] += drx;
        motionDataArray[4] += dry;
        motionDataArray[5] += drz;
        
        /*
        Send a self addressed flush event through the window system. This will
        trigger a Spaceball event if FreeCAD is ready to do so.
        */
        nMotionEvents++;
        XClientMessageEvent flushEvent;
        
        flushEvent.display = display;
        flushEvent.window = event->xclient.window;
        flushEvent.type = ClientMessage;
        flushEvent.format = 8;    
        flushEvent.message_type = motion_flush_event;
        
        XSendEvent (display, flushEvent.window, False, 0, (XEvent*)&flushEvent); // siehe spnavd, False, 0
        
        return true;
    }

    if (navEvent.type == SPNAV_EVENT_BUTTON)
    {
        Spaceball::ButtonEvent *buttonEvent = new Spaceball::ButtonEvent();
        buttonEvent->setButtonNumber(navEvent.button.bnum);
        if (navEvent.button.press)
            buttonEvent->setButtonStatus(Spaceball::BUTTON_PRESSED);
        else
            buttonEvent->setButtonStatus(Spaceball::BUTTON_RELEASED);
        this->postEvent(currentWidget, buttonEvent);
        return true;
    }

    Base::Console().Log("Unknown spaceball event\n");
    return true;
#else
    return false;
#endif // SPNAV_FOUND
}