Further work osgViewer::Viewer and related classes.

This commit is contained in:
Robert Osfield
2006-12-20 21:13:29 +00:00
parent 32821ebe4e
commit 2255771b74
18 changed files with 580 additions and 36 deletions

View File

@@ -50,9 +50,18 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced
/** Add an event to the end of the event queue.*/
void addEvent(GUIEventAdapter* event);
/** Specify if mouse coordinates should be transformed into a pre defined input range, or whether they
* should be simply based on as local coordinates to the window that generated the mouse events.*/
void setUseFixedMouseInputRange(bool useFixedMouseInputRange) { _useFixedMouseInputRange = useFixedMouseInputRange; }
/** Get whether the mouse coordinates should be transformed into a pre defined input range.*/
bool getUseFixedMouseInputRange() { return _useFixedMouseInputRange; }
/** Set the mouse input range.*/
void setMouseInputRange(float xMin, float yMin, float xMax, float yMax) { getCurrentEventState()->setInputRange(xMin, yMin, xMax, yMax); }
/** Method for adapting window resize event, placing this event on the back of the event queue. */
void windowResize(int x, int y, unsigned int width, unsigned int height, bool updateMouseRange = true);
void windowResize(int x, int y, unsigned int width, unsigned int height);
/** Method for adapting mouse scroll wheel events, placing this event on the back of the event queue. */
void mouseScroll(GUIEventAdapter::ScrollingMotion sm);
@@ -84,11 +93,11 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced
* Button numbering is 1 for left mouse button, 2 for middle, 3 for right. */
void mouseButtonRelease(float x, float y, unsigned int button);
/** Method for adapting keyboard press events.*/
void keyPress(GUIEventAdapter::KeySymbol key);
/** Method for adapting keyboard press events. Note, special keys such as Ctrl/Function keys should be adapted to GUIEventAdapter::KeySymbol mappings.*/
void keyPress(int key);
/** Method for adapting keyboard press events.*/
void keyRelease(GUIEventAdapter::KeySymbol key);
/** Method for adapting keyboard press events. Note, special keys such as Ctrl/Function keys should be adapted to GUIEventAdapter::KeySymbol mappings.*/
void keyRelease(int key);
/** Method for adapting frame events.*/
void frame(double t);
@@ -114,6 +123,8 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced
osg::ref_ptr<GUIEventAdapter> _accumulateEventState;
bool _useFixedMouseInputRange;
osg::Timer_t _startTick;
mutable OpenThreads::Mutex _eventQueueMutex;
Events _eventQueue;

View File

@@ -271,6 +271,7 @@ public:
/** deprecated function for getting time of event. */
double time() const { return _time; }
/** set window rectangle. */
void setWindowRectangle(int x, int y, unsigned int width, unsigned int height, bool updateMouseRange = true);

View File

@@ -40,6 +40,8 @@ class OSGVIEWER_EXPORT GraphicsWindow : public osg::GraphicsContext, public osgG
osgGA::EventQueue* getEventQueue() { return _eventQueue.get(); }
const osgGA::EventQueue* getEventQueue() const { return _eventQueue.get(); }
virtual void checkEvents() {}
public:
/** Realise the GraphicsContext implementation,

View File

@@ -16,6 +16,9 @@
* These elements are license under OSGPL as above, with Copyright (C) 2001-2004 Don Burns.
*/
#ifndef OSGVIEWER_GRAPHICSWINDOWX11
#define OSGVIEWER_GRAPHICSWINDOWX11 1
#include <osgViewer/Viewer>
#include <X11/X.h>
@@ -23,11 +26,16 @@
#include <X11/Xutil.h>
#include <X11/Xmd.h>
#include <X11/keysym.h>
#include <X11/Xmu/WinUtil.h>
#include <X11/cursorfont.h>
#define GLX_GLXEXT_PROTOTYPES 1
#include <GL/glx.h>
namespace osgViewer
{
class GraphicsContextX11 : public osg::GraphicsContext
{
public:
@@ -110,14 +118,20 @@ class GraphicsWindowX11 : public osgViewer::GraphicsWindow
/** Make this graphics context current.*/
virtual void makeCurrentImplementation();
/** swap the front and back buffers.*/
/** Swap the front and back buffers.*/
virtual void swapBuffersImplementation();
/** Check to see if any events have been generated.*/
virtual void checkEvents();
protected:
bool createVisualInfo();
void setBorder(bool flag);
void init();
void transformMouseXY(float& x, float& y);
void adaptKey(XKeyEvent& keyevent, int& keySymbol, unsigned int& modifierMask);
Display* _display;
Window _parent;
@@ -280,6 +294,7 @@ void GraphicsWindowX11::init()
XWindowAttributes watt;
XGetWindowAttributes( _display, _parent, &watt );
// unsigned int parentWindowHeight = watt.height;
osg::notify(osg::NOTICE)<<"First watt.x = "<<watt.x<<" watt.y="<<watt.y<<std::endl;
XSetWindowAttributes swatt;
swatt.colormap = XCreateColormap( _display, _parent, _visualInfo->visual, AllocNone);
@@ -322,8 +337,11 @@ void GraphicsWindowX11::init()
sh.height = _traits->_height;
XSetStandardProperties( _display, _window, _traits->_windowName.c_str(), _traits->_windowName.c_str(), None, 0, 0, &sh);
#if 1
setBorder(_traits->_windowDecoration);
#else
setBorder(true);
#endif
// Create default Cursor
_defaultCursor = XCreateFontCursor( _display, XC_left_ptr );
@@ -349,6 +367,13 @@ void GraphicsWindowX11::init()
XSync(_display,0);
}
XSelectInput( _display, _window, ExposureMask | StructureNotifyMask |
KeyPressMask | KeyReleaseMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
XFlush( _display );
XSync( _display, 0 );
_initialized = true;
}
@@ -403,9 +428,236 @@ void GraphicsWindowX11::swapBuffersImplementation()
glXSwapBuffers(_display, _window);
}
void GraphicsWindowX11::checkEvents()
{
// osg::notify(osg::NOTICE)<<"Check events"<<std::endl;
while( XPending(_display) )
{
XEvent ev;
XNextEvent( _display, &ev );
switch( ev.type )
{
case Expose :
osg::notify(osg::NOTICE)<<"Expose"<<std::endl;
break;
case GravityNotify :
osg::notify(osg::NOTICE)<<"GravityNotify"<<std::endl;
break;
case UnmapNotify :
osg::notify(osg::NOTICE)<<"UnmapNotify"<<std::endl;
break;
case ReparentNotify:
osg::notify(osg::NOTICE)<<"ReparentNotify"<<std::endl;
break;
case DestroyNotify :
osg::notify(osg::NOTICE)<<"DestroyNotify"<<std::endl;
_realized = false;
break;
case ConfigureNotify :
{
osg::notify(osg::NOTICE)<<"ConfigureNotify x="<<ev.xconfigure.x<<" y="<<ev.xconfigure.y<<" width="<<ev.xconfigure.width<<", height="<<ev.xconfigure.height<<std::endl;
_traits->_x = ev.xconfigure.x;
_traits->_y = ev.xconfigure.y;
_traits->_width = ev.xconfigure.width;
_traits->_height = ev.xconfigure.height;
// need to dispatch resize event.
break;
}
case MapNotify :
{
osg::notify(osg::NOTICE)<<"MapNotify"<<std::endl;
XWindowAttributes watt;
do
XGetWindowAttributes(_display, _window, &watt );
while( watt.map_state != IsViewable );
XSetInputFocus( _display, _window, RevertToNone, CurrentTime );
XFlush(_display); XSync(_display,0);
break;
}
case MotionNotify :
{
int wx, wy;
Window win = 0L;
if( ev.xmotion.same_screen )
{
wx = ev.xmotion.x;
wy = ev.xmotion.y;
}
else
{
// the mouse in on another screen so need to compute the
// coordinates of the mouse position relative to an absolute position
// then take away the position of the original window/screen to get
// the coordinates relative to the original position.
Window root;
int rx, ry;
unsigned int buttons;
int screenOrigin_x = 0;
int screenOrigin_y = 0;
int i;
for(i= 0; i < ScreenCount(_display); i++ )
{
if( XQueryPointer( _display, RootWindow(_display, i),
&root, &win, &rx, &ry, &wx, &wy, &buttons) )
{
break;
}
screenOrigin_x += DisplayWidth(_display, i);
}
for(i= 0; i < static_cast<int>(_traits->_screenNum); i++ )
{
screenOrigin_x -= DisplayWidth(_display, i);
}
wx += (screenOrigin_x - _traits->_x);
wy += (screenOrigin_y - _traits->_y);
}
float mx = wx;
float my = wy;
transformMouseXY(mx, my);
getEventQueue()->mouseMotion(mx, my);
break;
}
case ButtonPress :
{
if( ev.xbutton.button == Button4 )
{
getEventQueue()->mouseScroll(osgGA::GUIEventAdapter::SCROLL_UP);
}
else if( ev.xbutton.button == Button5)
{
getEventQueue()->mouseScroll(osgGA::GUIEventAdapter::SCROLL_DOWN);
}
else
{
float mx = ev.xbutton.x;
float my = ev.xmotion.y;
transformMouseXY(mx, my);
getEventQueue()->mouseButtonPress(mx, my, ev.xbutton.button);
}
break;
}
case ButtonRelease :
{
if( ev.xbutton.button == Button4 )
{
getEventQueue()->mouseScroll(osgGA::GUIEventAdapter::SCROLL_UP);
}
else if( ev.xbutton.button == Button5)
{
getEventQueue()->mouseScroll(osgGA::GUIEventAdapter::SCROLL_DOWN);
}
else
{
float mx = ev.xbutton.x;
float my = ev.xmotion.y;
transformMouseXY(mx, my);
getEventQueue()->mouseButtonRelease(mx, my, ev.xbutton.button);
}
break;
}
case KeyPress:
{
int keySymbol = 0;
unsigned int modifierMask = 0;
adaptKey(ev.xkey, keySymbol, modifierMask);
getEventQueue()->keyPress(keySymbol);
getEventQueue()->getCurrentEventState()->setModKeyMask(modifierMask);
break;
}
case KeyRelease:
{
int keySymbol = 0;
unsigned int modifierMask = 0;
adaptKey(ev.xkey, keySymbol, modifierMask);
getEventQueue()->keyRelease(keySymbol);
getEventQueue()->getCurrentEventState()->setModKeyMask(modifierMask);
break;
}
default:
osg::notify(osg::NOTICE)<<"Other event"<<std::endl;
break;
}
}
}
void GraphicsWindowX11::transformMouseXY(float& x, float& y)
{
if (getEventQueue()->getUseFixedMouseInputRange())
{
osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
x = eventState->getXmin() + (eventState->getXmax()-eventState->getXmin())*x/float(_traits->_width);
y = eventState->getYmin() + (eventState->getYmax()-eventState->getYmin())*y/float(_traits->_height);
}
}
void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, unsigned int& modifierMask)
{
// KeySym ks = XKeycodeToKeysym( _display, keyevent.keycode, 0 );
static XComposeStatus state;
unsigned char keybuf[32];
XLookupString( &keyevent, (char *)keybuf, sizeof(keybuf), NULL, &state );
modifierMask = 0;
if( keyevent.state & ShiftMask )
{
modifierMask |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
}
if( keyevent.state & LockMask )
{
modifierMask |= osgGA::GUIEventAdapter::MODKEY_CAPS_LOCK;
}
if( keyevent.state & ControlMask )
{
modifierMask |= osgGA::GUIEventAdapter::MODKEY_CTRL;
}
if( keyevent.state & Mod1Mask )
{
modifierMask |= osgGA::GUIEventAdapter::MODKEY_ALT;
}
if( keyevent.state & Mod2Mask )
{
modifierMask |= osgGA::GUIEventAdapter::MODKEY_NUM_LOCK;
}
if( keyevent.state & Mod4Mask )
{
modifierMask |= osgGA::GUIEventAdapter::MODKEY_META;
}
keySymbol = keybuf[0];
}
struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface
{
X11WindowingSystemInterface()
{
}
virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si)
{
const char* displayString = si._hostName.c_str();
@@ -453,6 +705,7 @@ struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSyste
return new GraphicsWindowX11(traits);
}
}
};
struct RegisterWindowingSystemInterfaceProxy
@@ -469,3 +722,7 @@ struct RegisterWindowingSystemInterfaceProxy
};
RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy;
}
#endif

View File

@@ -39,6 +39,7 @@ class OSGVIEWER_EXPORT Scene : public virtual osg::Referenced
osg::Node* getSceneData();
const osg::Node* getSceneData() const;
osg::FrameStamp* getFrameStamp() { return _frameStamp.get(); }
void setEventQueue(osgGA::EventQueue* eventQueue) { _eventQueue = eventQueue; }
osgGA::EventQueue* getEventQueue() { return _eventQueue.get(); }

View File

@@ -31,6 +31,10 @@ class OSGVIEWER_EXPORT View : public osg::View
osg::Node* getSceneData() { return _scene.valid() ? _scene->getSceneData() : 0; }
const osg::Node* getSceneData() const { return _scene.valid() ? _scene->getSceneData() : 0; }
void setEventQueue(osgGA::EventQueue* eventQueue) { _eventQueue = eventQueue; }
osgGA::EventQueue* getEventQueue() { return _eventQueue.get(); }
const osgGA::EventQueue* getEventQueue() const { return _eventQueue.get(); }
void setCameraManipulator(osgGA::MatrixManipulator* manipulator);
osgGA::MatrixManipulator* getCameraManipulator() { return _cameraManipulator.get(); }
const osgGA::MatrixManipulator* getCameraManipulator() const { return _cameraManipulator.get(); }
@@ -56,6 +60,7 @@ class OSGVIEWER_EXPORT View : public osg::View
virtual ~View();
osg::ref_ptr<osgViewer::Scene> _scene;
osg::ref_ptr<osgGA::EventQueue> _eventQueue;
osg::ref_ptr<osgGA::MatrixManipulator> _cameraManipulator;
EventHandlers _eventHandlers;

View File

@@ -52,6 +52,7 @@ class OSGVIEWER_EXPORT Viewer : public osgViewer::View
public:
void init();
bool _firstFrame;
protected: