Esempio n. 1
0
void Config::_switchView()
{
    const eq::Canvases& canvases = getCanvases();
    if( !_currentCanvas && !canvases.empty( ))
        _currentCanvas = canvases.front();

    if( !_currentCanvas )
        return;

    const eq::Layout* layout = _currentCanvas->getActiveLayout();
    if( !layout )
        return;

    const View* view = _getCurrentView();
    const eq::Views& views = layout->getViews();
    LBASSERT( !views.empty( ));

    if( !view )
    {
        _frameData.setCurrentViewID( views.front()->getID( ));
        return;
    }

    eq::ViewsCIter i = std::find( views.begin(), views.end(), view );
    if( i != views.end( ))
        ++i;
    if( i == views.end( ))
        _frameData.setCurrentViewID( eq::UUID( ));
    else
        _frameData.setCurrentViewID( (*i)->getID( ));
}
Esempio n. 2
0
bool Config::init()
{
    if( !_animation.isValid( ))
        _animation.loadAnimation( _initData.getPathFilename( ));

    // init distributed objects
    if( !_initData.useColor( ))
        _frameData.setColorMode( COLOR_WHITE );

    _frameData.setRenderMode( _initData.getRenderMode( ));
    registerObject( &_frameData );
    _frameData.setAutoObsolete( getLatency( ));

    _initData.setFrameDataID( _frameData.getID( ));
    registerObject( &_initData );

    // init config
    if( !eq::Config::init( _initData.getID( )))
    {
        _deregisterData();
        return false;
    }

    _loadModels();
    _registerModels();

    const eq::Canvases& canvases = getCanvases();
    if( canvases.empty( ))
        _currentCanvas = 0;
    else
        _currentCanvas = canvases.front();

    _setMessage( "Welcome to eqPly\nPress F1 for help" );
    return true;
}
Esempio n. 3
0
bool Config::init()
{
    // init distributed objects
    LBCHECK(registerObject(&_frameData));

    _frameData.setOrtho(_initData.getOrtho());
    _initData.setFrameDataID(_frameData.getID());

    _frameData.setAutoObsolete(getLatency());

    LBCHECK(registerObject(&_initData));

    // init config
    if (!eq::Config::init(_initData.getID()))
    {
        _deregisterData();
        return false;
    }

    const eq::Canvases& canvases = getCanvases();
    if (canvases.empty())
        _currentCanvas = 0;
    else
        _currentCanvas = canvases.front();

    _setMessage("Welcome to eVolve\nPress F1 for help");

    return true;
}
Esempio n. 4
0
//---------------------------------------------------------------------------
// update running entities (init/exit/runtime change)
//---------------------------------------------------------------------------
bool Config::_updateRunning( const bool canFail )
{
    if( _state == STATE_STOPPED )
        return true;

    LBASSERT( _state == STATE_RUNNING || _state == STATE_INITIALIZING ||
              _state == STATE_EXITING );

    if( !_connectNodes() && !canFail )
        return false;

    _startNodes();
    _updateCanvases();
    const bool result = _updateNodes( canFail );
    _stopNodes();

    // Don't use visitor, it would get confused with modified child vectors
    _deleteEntities( getCanvases( ));
    _deleteEntities( getLayouts( ));
    _deleteEntities( getObservers( ));
    const Nodes& nodes = getNodes();
    for( Nodes::const_iterator i = nodes.begin(); i != nodes.end(); ++i )
    {
        const Pipes& pipes = (*i)->getPipes();
        for( Pipes::const_iterator j = pipes.begin(); j != pipes.end(); ++j )
        {
            const Windows& windows = (*j)->getWindows();
            _deleteEntities( windows );
        }
    }

    return result;
}
Esempio n. 5
0
void Config::_updateCanvases()
{
    const Canvases& canvases = getCanvases();
    for( Canvases::const_iterator i = canvases.begin(); i != canvases.end();++i)
    {
        Canvas* canvas = *i;
        if( canvas->needsDelete( ))
            canvas->exit();
    }
}
Esempio n. 6
0
bool Config::init()
{
    if( !_animation.isValid( ))
        _animation.loadAnimation( _initData.getPathFilename( ));

    // init distributed objects
    if( !_initData.useColor( ))
        _frameData.setColorMode( COLOR_WHITE );

    _frameData.setRenderMode( _initData.getRenderMode( ));
    registerObject( &_frameData );
    _frameData.setAutoObsolete( getLatency( ));

    _initData.setFrameDataID( _frameData.getID( ));
    registerObject( &_initData );

    // init config
    if( !eq::Config::init( _initData.getID( )))
    {
        _deregisterData();
        return false;
    }

    _loadModels();
    _registerModels();

    // init tracker
    if( !_initData.getTrackerPort().empty( ))
    {
        if( !_tracker.init( _initData.getTrackerPort() ))
            LBWARN << "Failed to initialize tracker" << std::endl;
        else
        {
            // Set up position of tracking system wrt world space
            // Note: this depends on the physical installation.
            eq::Matrix4f m( eq::Matrix4f::IDENTITY );
            m.scale( 1.f, 1.f, -1.f );
            _tracker.setWorldToEmitter( m );

            m = eq::Matrix4f::IDENTITY;
            m.rotate_z( -M_PI_2 );
            _tracker.setSensorToObject( m );
            LBINFO << "Tracker initialized" << std::endl;
        }
    }

    const eq::Canvases& canvases = getCanvases();
    if( canvases.empty( ))
        _currentCanvas = 0;
    else
        _currentCanvas = canvases.front();

    _setMessage( "Welcome to eqPly\nPress F1 for help" );
    return true;
}
Esempio n. 7
0
//---------------------------------------------------------------------------
// init
//---------------------------------------------------------------------------
bool Config::_init( const uint128_t& initID )
{
    LBASSERT( _state == STATE_STOPPED );
    _state = STATE_INITIALIZING;
    _currentFrame  = 0;
    _finishedFrame = 0;
    _initID = initID;

    for( auto compound : _compounds )
        compound->init();

    for( auto observer : getObservers( ))
        observer->init();

    for( auto canvas : getCanvases( ))
        canvas->init();

    const auto& layouts = getLayouts();
    for( auto layout : layouts )
        for( auto view : layout->getViews( ))
            view->init();

    // any of the above entities might have been updated
    commit();

    if( !_updateRunning( false ))
        return false;

    // Needed to set up active state for first LB update
    for( CompoundsCIter i = _compounds.begin(); i != _compounds.end(); ++i )
        (*i)->update( 0 );

    // Update equalizer properties in views
    UpdateEqualizersVisitor updater;
    accept( updater );

    _needsFinish = false;
    _state = STATE_RUNNING;
    return true;
}
Esempio n. 8
0
//---------------------------------------------------------------------------
// exit
//---------------------------------------------------------------------------
bool Config::exit()
{
    if( _state != STATE_RUNNING )
        LBWARN << "Exiting non-initialized config" << std::endl;

    LBASSERT( _state == STATE_RUNNING || _state == STATE_INITIALIZING );
    _state = STATE_EXITING;

    const Canvases& canvases = getCanvases();
    for( Canvases::const_iterator i = canvases.begin();
         i != canvases.end(); ++i )
    {
        Canvas* canvas = *i;
        canvas->exit();
    }

    for( Compounds::const_iterator i = _compounds.begin();
         i != _compounds.end(); ++i )
    {
        Compound* compound = *i;
        compound->exit();
    }

    const bool success = _updateRunning( true );

    // send exit event to app, needed if this is called from init()
    EventOCommand cmd( send( findApplicationNetNode(),
                             fabric::CMD_CONFIG_EVENT ));
    Event event;
    event.serial = getSerial();
    event.time = getServer()->getTime();
    event.originator = getID();

    cmd << EVENT_EXIT << event;

    _needsFinish = false;
    _state = STATE_STOPPED;
    return success;
}
Esempio n. 9
0
void Config::_switchCanvas()
{
    const eq::Canvases& canvases = getCanvases();
    if( canvases.empty( ))
        return;

    _frameData.setCurrentViewID( eq::UUID( ));

    if( !_currentCanvas )
    {
        _currentCanvas = canvases.front();
        return;
    }

    eq::CanvasesCIter i = stde::find( canvases, _currentCanvas );
    LBASSERT( i != canvases.end( ));

    ++i;
    if( i == canvases.end( ))
        _currentCanvas = canvases.front();
    else
        _currentCanvas = *i;
    _switchView(); // activate first view on canvas
}
Esempio n. 10
0
//---------------------------------------------------------------------------
// exit
//---------------------------------------------------------------------------
bool Config::exit()
{
    if( _state != STATE_RUNNING )
        LBWARN << "Exiting non-initialized config" << std::endl;

    LBASSERT( _state == STATE_RUNNING || _state == STATE_INITIALIZING );
    _state = STATE_EXITING;

    const Canvases& canvases = getCanvases();
    for( Canvases::const_iterator i = canvases.begin();
         i != canvases.end(); ++i )
    {
        Canvas* canvas = *i;
        canvas->exit();
    }

    for( Compounds::const_iterator i = _compounds.begin();
         i != _compounds.end(); ++i )
    {
        Compound* compound = *i;
        compound->exit();
    }

    const bool success = _updateRunning( true );

    // TODO: is this needed? sender of CMD_CONFIG_EXIT is the appNode itself
    // which sets the running state to false anyway. Besides, this event is
    // not handled by the appNode because it is already in exiting procedure
    // and does not call handleEvents anymore
    // eile: May be needed for reliability?
    send( findApplicationNetNode(), fabric::CMD_CONFIG_EVENT ) << Event::EXIT;

    _needsFinish = false;
    _state = STATE_STOPPED;
    return success;
}
Esempio n. 11
0
bool Config::handleEvent( eq::EventICommand command )
{
    switch( command.getEventType( ))
    {
        case eq::Event::KEY_PRESS:
        {
            const eq::Event& event = command.get< eq::Event >();
            if( _handleKeyEvent( event.keyPress ))
            {
                _redraw = true;
                return true;
            }
            break;
        }

        case eq::Event::CHANNEL_POINTER_BUTTON_PRESS:
        {
            const eq::Event& event = command.get< eq::Event >();
            const eq::uint128_t& viewID = event.context.view.identifier;
            _frameData.setCurrentViewID( viewID );
            if( viewID == 0 )
            {
                _currentCanvas = 0;
                return false;
            }

            const View* view = _getCurrentView();
            const eq::Layout* layout = view->getLayout();
            const eq::Canvases& canvases = getCanvases();
            for( eq::CanvasesCIter i = canvases.begin();
                 i != canvases.end(); ++i )
            {
                eq::Canvas* canvas = *i;
                const eq::Layout* canvasLayout = canvas->getActiveLayout();

                if( canvasLayout == layout )
                {
                    _currentCanvas = canvas;
                    return true;
                }
            }
            return true;
        }

        case eq::Event::CHANNEL_POINTER_BUTTON_RELEASE:
        {
            const eq::Event& event = command.get< eq::Event >();
            const eq::PointerEvent& releaseEvent =
                event.pointerButtonRelease;
            if( releaseEvent.buttons == eq::PTR_BUTTON_NONE)
            {
                if( releaseEvent.button == eq::PTR_BUTTON1 )
                {
                    _spinX = releaseEvent.dy;
                    _spinY = releaseEvent.dx;
                    _redraw = true;
                    return true;
                }
                if( releaseEvent.button == eq::PTR_BUTTON2 )
                {
                    _advance = -releaseEvent.dy;
                    _redraw = true;
                    return true;
                }
            }
            break;
        }
        case eq::Event::CHANNEL_POINTER_MOTION:
        {
            const eq::Event& event = command.get< eq::Event >();
            switch( event.pointerMotion.buttons )
            {
              case eq::PTR_BUTTON1:
                  _spinX = 0;
                  _spinY = 0;

                  if( _frameData.usePilotMode())
                      _frameData.spinCamera(
                          -0.005f * event.pointerMotion.dy,
                          -0.005f * event.pointerMotion.dx );
                  else
                      _frameData.spinModel(
                          -0.005f * event.pointerMotion.dy,
                          -0.005f * event.pointerMotion.dx, 0.f );
                  _redraw = true;
                  return true;

              case eq::PTR_BUTTON2:
                  _advance = -event.pointerMotion.dy;
                  _frameData.moveCamera( 0.f, 0.f, .005f * _advance );
                  _redraw = true;
                  return true;

              case eq::PTR_BUTTON3:
                  _frameData.moveCamera(  .0005f * event.pointerMotion.dx,
                                         -.0005f * event.pointerMotion.dy,
                                          0.f );
                  _redraw = true;
                  return true;
            }
            break;
        }

        case eq::Event::CHANNEL_POINTER_WHEEL:
        {
            const eq::Event& event = command.get< eq::Event >();
            _frameData.moveCamera( -0.05f * event.pointerWheel.yAxis,
                                   0.f,
                                   0.05f * event.pointerWheel.xAxis );
            _redraw = true;
            return true;
        }

        case eq::Event::MAGELLAN_AXIS:
        {
            const eq::Event& event = command.get< eq::Event >();
            _spinX = 0;
            _spinY = 0;
            _advance = 0;
            _frameData.spinModel( 0.0001f * event.magellan.xRotation,
                                  0.0001f * event.magellan.yRotation,
                                  0.0001f * event.magellan.zRotation );
            _frameData.moveCamera( 0.0001f * event.magellan.xAxis,
                                   0.0001f * event.magellan.yAxis,
                                   0.0001f * event.magellan.zAxis );
            _redraw = true;
            return true;
        }

        case eq::Event::MAGELLAN_BUTTON:
        {
            const eq::Event& event = command.get< eq::Event >();
            if( event.magellan.button == eq::PTR_BUTTON1 )
                _frameData.toggleColorMode();

            _redraw = true;
            return true;
        }

        case eq::Event::WINDOW_EXPOSE:
        case eq::Event::WINDOW_RESIZE:
        case eq::Event::WINDOW_CLOSE:
        case eq::Event::VIEW_RESIZE:
            _redraw = true;
            break;

        case IDLE_AA_LEFT:
            if( _useIdleAA )
            {
                const int32_t steps = command.get< int32_t >();
                _numFramesAA = LB_MAX( _numFramesAA, steps );
            }
            else
                _numFramesAA = 0;
            return false;

        default:
            break;
    }

    _redraw |= eq::Config::handleEvent( command );
    return _redraw;
}
Esempio n. 12
0
void Config::activateCanvas( Canvas* canvas )
{
    LBASSERT( canvas->isStopped( ));
    LBASSERT( lunchbox::find( getCanvases(), canvas ) != getCanvases().end( ));

    const Layouts& layouts = canvas->getLayouts();
    const Segments& segments = canvas->getSegments();

    for( Layouts::const_iterator i = layouts.begin();
         i != layouts.end(); ++i )
    {
        const Layout* layout = *i;
        if( !layout )
            continue;

        const Views& views = layout->getViews();
        for( Views::const_iterator j = views.begin();
             j != views.end(); ++j )
        {
            View* view = *j;

            for( Segments::const_iterator k = segments.begin();
                 k != segments.end(); ++k )
            {
                Segment* segment = *k;
                Viewport viewport = segment->getViewport();
                viewport.intersect( view->getViewport( ));

                if( !viewport.hasArea( ))
                {
                    LBLOG( LOG_VIEW )
                        << "View " << view->getName() << view->getViewport()
                        << " doesn't intersect " << segment->getName()
                        << segment->getViewport() << std::endl;

                    continue;
                }

                Channel* segmentChannel = segment->getChannel();
                if( !segmentChannel )
                {
                    LBWARN << "Segment " << segment->getName()
                           << " has no output channel" << std::endl;
                    continue;
                }

                if ( findChannel( segment, view ))
                    continue;

                // create and add new channel
                Channel* channel = new Channel( *segmentChannel );
                channel->init(); // not in ctor, virtual method
                channel->setOutput( view, segment );

                //----- compute channel viewport:
                // segment/view intersection in canvas space...
                Viewport contribution = viewport;
                // ... in segment space...
                contribution.transform( segment->getViewport( ));

                // segment output area
                if( segmentChannel->hasFixedViewport( ))
                {
                    Viewport subViewport = segmentChannel->getViewport();
                    LBASSERT( subViewport.isValid( ));
                    if( !subViewport.isValid( ))
                        subViewport = eq::fabric::Viewport::FULL;

                    // ...our part of it
                    subViewport.apply( contribution );
                    channel->setViewport( subViewport );
                    LBLOG( LOG_VIEW )
                        << "View @" << (void*)view << ' ' << view->getViewport()
                        << " intersects " << segment->getName()
                        << segment->getViewport() << " at " << subViewport
                        << " using channel @" << (void*)channel << std::endl;
                }
                else
                {
                    PixelViewport pvp = segmentChannel->getPixelViewport();
                    LBASSERT( pvp.isValid( ));
                    pvp.apply( contribution );
                    channel->setPixelViewport( pvp );
                    LBLOG( LOG_VIEW )
                        << "View @" << (void*)view << ' ' << view->getViewport()
                        << " intersects " << segment->getName()
                        << segment->getViewport() << " at " << pvp
                        << " using channel @" << (void*)channel << std::endl;
                }

                if( channel->getWindow()->isAttached( ))
                    // parent is already registered - register channel as well
                    getServer()->registerObject( channel );
            }
        }
    }
}
Esempio n. 13
0
bool Config::handleEvent(const eq::EventType type,
                         const eq::PointerEvent& event)
{
    switch (type)
    {
    case eq::EVENT_CHANNEL_POINTER_BUTTON_PRESS:
    {
        const eq::uint128_t& viewID = event.context.view.identifier;
        _frameData.setCurrentViewID(viewID);
        if (viewID == 0)
        {
            _currentCanvas = 0;
            return true;
        }

        const eq::View* view = find<eq::View>(viewID);
        const eq::Layout* layout = view->getLayout();
        const eq::Canvases& canvases = getCanvases();
        for (eq::Canvas* canvas : canvases)
        {
            const eq::Layout* canvasLayout = canvas->getActiveLayout();

            if (canvasLayout == layout)
            {
                _currentCanvas = canvas;
                return true;
            }
        }
        break;
    }

    case eq::EVENT_CHANNEL_POINTER_BUTTON_RELEASE:
        if (event.buttons == eq::PTR_BUTTON_NONE &&
            event.button == eq::PTR_BUTTON1)
        {
            _spinY = event.dx;
            _spinX = event.dy;
            return true;
        }
        break;

    case eq::EVENT_CHANNEL_POINTER_MOTION:
        if (event.buttons == eq::PTR_BUTTON1)
        {
            _spinX = 0;
            _spinY = 0;

            _frameData.spinCamera(-0.005f * event.dy, -0.005f * event.dx);
            return true;
        }
        if (event.buttons == eq::PTR_BUTTON2 ||
            event.buttons == (eq::PTR_BUTTON1 | eq::PTR_BUTTON3))
        {
            _frameData.moveCamera(.0, .0, .005f * event.dy);
            return true;
        }
        if (event.buttons == eq::PTR_BUTTON3)
        {
            _frameData.moveCamera(.0005f * event.dx, -.0005f * event.dy, .0f);
            return true;
        }
        break;

    default:
        break;
    }
    return eq::Config::handleEvent(type, event);
}
Esempio n. 14
0
bool Config::handleEvent(const eq::EventType type, const eq::KeyEvent& event)
{
    if (type != eq::EVENT_KEY_PRESS)
        return eq::Config::handleEvent(type, event);

    switch (event.key)
    {
    case 'b':
    case 'B':
        _frameData.toggleBackground();
        return true;

    case 'd':
    case 'D':
        _frameData.toggleColorMode();
        return true;

    case eq::KC_F1:
    case 'h':
    case 'H':
        _frameData.toggleHelp();
        return true;

    case 'r':
    case 'R':
    case ' ':
        _spinX = 0;
        _spinY = 0;
        _frameData.reset();
        return true;

    case 'n':
    case 'N':
        _frameData.toggleNormalsQuality();
        return true;

    case 'o':
    case 'O':
        _frameData.toggleOrtho();
        return true;

    case 's':
    case 'S':
        _frameData.toggleStatistics();
        return true;

    case 'l':
        _switchLayout(1);
        return true;
    case 'L':
        _switchLayout(-1);
        return true;

    case 'q':
        _frameData.adjustQuality(-.1f);
        return true;

    case 'Q':
        _frameData.adjustQuality(.1f);
        return true;

    case 'c':
    case 'C':
    {
        const eq::Canvases& canvases = getCanvases();
        if (canvases.empty())
            return true;

        _frameData.setCurrentViewID(co::uint128_t());

        if (!_currentCanvas)
        {
            _currentCanvas = canvases.front();
            return true;
        }

        eq::Canvases::const_iterator i =
            std::find(canvases.begin(), canvases.end(), _currentCanvas);
        LBASSERT(i != canvases.end());

        ++i;
        if (i == canvases.end())
            _currentCanvas = canvases.front();
        else
            _currentCanvas = *i;
        return true;
    }

    case 'v':
    case 'V':
    {
        const eq::Canvases& canvases = getCanvases();
        if (!_currentCanvas && !canvases.empty())
            _currentCanvas = canvases.front();

        if (!_currentCanvas)
            return true;

        const eq::Layout* layout = _currentCanvas->getActiveLayout();
        if (!layout)
            return true;

        const eq::View* current = find<eq::View>(_frameData.getCurrentViewID());

        const eq::Views& views = layout->getViews();
        LBASSERT(!views.empty());

        if (!current)
        {
            _frameData.setCurrentViewID(views.front()->getID());
            return true;
        }

        eq::Views::const_iterator i =
            std::find(views.begin(), views.end(), current);
        LBASSERT(i != views.end());

        ++i;
        if (i == views.end())
            _frameData.setCurrentViewID(co::uint128_t());
        else
            _frameData.setCurrentViewID((*i)->getID());
        return true;
    }

    default:
        break;
    }
    return eq::Config::handleEvent(type, event);
}
Esempio n. 15
0
bool Config::handleEvent( const eq::ConfigEvent* event )
{
    switch( event->data.type )
    {
        case eq::Event::KEY_PRESS:
            if( _handleKeyEvent( event->data.keyPress ))
                return true;
            break;

        case eq::Event::CHANNEL_POINTER_BUTTON_PRESS:
        {
            const co::base::UUID& viewID = event->data.context.view.identifier;
            _frameData.setCurrentViewID( viewID );
            if( viewID == co::base::UUID::ZERO )
            {
                _currentCanvas = 0;
                return true;
            }
            
            const eq::View* view = find< eq::View >( viewID );
            const eq::Layout* layout = view->getLayout();
            const eq::Canvases& canvases = getCanvases();
            for( eq::Canvases::const_iterator i = canvases.begin();
                 i != canvases.end(); ++i )
            {
                eq::Canvas* canvas = *i;
                const eq::Layout* canvasLayout = canvas->getActiveLayout();

                if( canvasLayout == layout )
                {
                    _currentCanvas = canvas;
                    return true;
                }
            }
            return true;
        }

        case eq::Event::CHANNEL_POINTER_BUTTON_RELEASE:
            if( event->data.pointerButtonRelease.buttons == eq::PTR_BUTTON_NONE
                && event->data.pointerButtonRelease.button  == eq::PTR_BUTTON1 )
            {
                _spinY = event->data.pointerButtonRelease.dx;
                _spinX = event->data.pointerButtonRelease.dy;
            }
            return true;

        case eq::Event::CHANNEL_POINTER_MOTION:
            if( event->data.pointerMotion.buttons == eq::PTR_BUTTON_NONE )
                return true;

            if( event->data.pointerMotion.buttons == eq::PTR_BUTTON1 )
            {
                _spinX = 0;
                _spinY = 0;

                _frameData.spinCamera(  -0.005f * event->data.pointerMotion.dy,
                                        -0.005f * event->data.pointerMotion.dx);
            }
            else if( event->data.pointerMotion.buttons == eq::PTR_BUTTON2 ||
                     event->data.pointerMotion.buttons == ( eq::PTR_BUTTON1 |
                                                       eq::PTR_BUTTON3 ))
            {
                _frameData.moveCamera( .0, .0,
                                        .005f*event->data.pointerMotion.dy);
            }
            else if( event->data.pointerMotion.buttons == eq::PTR_BUTTON3 )
            {
                _frameData.moveCamera( .0005f * event->data.pointerMotion.dx,
                                      -.0005f * event->data.pointerMotion.dy, 
                                       .0 );
            }
            return true;

        default:
            break;
    }
    return eq::Config::handleEvent( event );
}
Esempio n. 16
0
bool Config::_handleKeyEvent( const eq::KeyEvent& event )
{
    switch( event.key )
    {
        case eq::KC_F1:
        case 'h':
        case 'H':
            _frameData.toggleHelp();
            return true;

        case 'r':
        case 'R':
        case ' ':
            _spinX = 0;
            _spinY = 0;
            _frameData.reset();
            return true;

        case 'o':
        case 'O':
            _frameData.toggleOrtho();
            return true;

        case 's':
        case 'S':
        _frameData.toggleStatistics();
            return true;

        case 'l':
            _switchLayout( 1 );
            return true;
        case 'L':
            _switchLayout( -1 );
            return true;

        case 'q':
            _frameData.adjustQuality( -.1f );
            return true;

        case 'Q':
            _frameData.adjustQuality( .1f );
            return true;

        case 'c':
        case 'C':
        {
            const eq::Canvases& canvases = getCanvases();
            if( canvases.empty( ))
                return true;

            _frameData.setCurrentViewID( co::base::UUID::ZERO );

            if( !_currentCanvas )
            {
                _currentCanvas = canvases.front();
                return true;
            }

            eq::Canvases::const_iterator i = std::find( canvases.begin(),
                                                        canvases.end(),
                                                        _currentCanvas );
            EQASSERT( i != canvases.end( ));

            ++i;
            if( i == canvases.end( ))
                _currentCanvas = canvases.front();
            else
                _currentCanvas = *i;
            return true;
        }

        case 'v':
        case 'V':
        {
            const eq::Canvases& canvases = getCanvases();
            if( !_currentCanvas && !canvases.empty( ))
                _currentCanvas = canvases.front();

            if( !_currentCanvas )
                return true;

            const eq::Layout* layout = _currentCanvas->getActiveLayout();
            if( !layout )
                return true;

            const eq::View* current = 
                              find< eq::View >( _frameData.getCurrentViewID( ));

            const eq::Views& views = layout->getViews();
            EQASSERT( !views.empty( ))

            if( !current )
            {
                _frameData.setCurrentViewID( views.front()->getID( ));
                return true;
            }

            eq::Views::const_iterator i = std::find( views.begin(),
                                                          views.end(),
                                                          current );
            EQASSERT( i != views.end( ));

            ++i;
            if( i == views.end( ))
                _frameData.setCurrentViewID( co::base::UUID::ZERO );
            else
                _frameData.setCurrentViewID( (*i)->getID( ));
            return true;
        }

        default:
            break;
    }
    return false;
}