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; } } }
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 }
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); }
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; }
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; }
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 ); }
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 }