Changed GraphicsWindowX11 so that it creates two Display* connextions to the Xserver,

one for the graphics thread, one for the main thread that querries events
This commit is contained in:
Robert Osfield
2007-02-09 13:51:28 +00:00
parent 162d08f541
commit 2a9d2bb25a
2 changed files with 95 additions and 40 deletions

View File

@@ -36,6 +36,7 @@ class GraphicsWindowX11 : public osgViewer::GraphicsWindow
GraphicsWindowX11(osg::GraphicsContext::Traits* traits):
_valid(false),
_display(0),
_eventDisplay(0),
_parent(0),
_window(0),
_visualInfo(0),
@@ -101,6 +102,7 @@ class GraphicsWindowX11 : public osgViewer::GraphicsWindow
// X11 specific aces functions
Display* getDisplay() { return _display; }
Display* getEventDisplay() { return _eventDisplay; }
Window& getParent() { return _parent; }
Window& getWindow() { return _window; }
@@ -120,6 +122,7 @@ class GraphicsWindowX11 : public osgViewer::GraphicsWindow
bool _valid;
Display* _display;
Display* _eventDisplay;
Window _parent;
Window _window;
XVisualInfo* _visualInfo;

View File

@@ -275,8 +275,10 @@ bool GraphicsWindowX11::createVisualInfo()
void GraphicsWindowX11::setWindowDecoration(bool flag)
{
Display* display = _display;
Atom atom;
if( (atom = XInternAtom( _display, "_MOTIF_WM_HINTS", 0 )) != None )
if( (atom = XInternAtom( display, "_MOTIF_WM_HINTS", 0 )) != None )
{
// Hack for sending 64 bit atom to Xserver
#if defined( _MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64) || defined ( __ia64 ) || defined (__amd64 ) || defined(__x86_64__)
@@ -322,16 +324,16 @@ void GraphicsWindowX11::setWindowDecoration(bool flag)
wmHints.input_mode = 0;
#endif
XUnmapWindow(_display, _window );
XChangeProperty( _display, _window, atom, atom, 32, PropModeReplace, (unsigned char *)&wmHints, 5 );
XMapWindow(_display, _window );
XUnmapWindow(display, _window );
XChangeProperty( display, _window, atom, atom, 32, PropModeReplace, (unsigned char *)&wmHints, 5 );
XMapWindow(display, _window );
XFlush(_display);
XSync(_display,0);
XFlush(display);
XSync(display,0);
#if 0
// now update the window dimensions to account for any size changes made by the window manager,
XGetWindowAttributes( _display, _window, &watt );
XGetWindowAttributes( display, _window, &watt );
_traits->width = watt.width;
_traits->height = watt.height;
#endif
@@ -343,6 +345,8 @@ void GraphicsWindowX11::setWindowDecoration(bool flag)
void GraphicsWindowX11::useCursor(bool cursorOn)
{
Display* display = _display;
if (cursorOn)
{
_currentCursor = _defaultCursor;
@@ -352,11 +356,11 @@ void GraphicsWindowX11::useCursor(bool cursorOn)
_currentCursor = _nullCursor;
}
if (_display && _window)
if (display && _window)
{
XDefineCursor( _display, _window, _currentCursor );
XFlush(_display);
XSync(_display,0);
XDefineCursor( display, _window, _currentCursor );
XFlush(display);
XSync(display,0);
}
_traits->useCursor = cursorOn;
@@ -470,6 +474,9 @@ void GraphicsWindowX11::init()
return;
}
_eventDisplay = XOpenDisplay(_traits->displayName().c_str());
// This positions the window at _windowX, _windowY
XSizeHints sh;
sh.flags = 0;
@@ -504,9 +511,9 @@ void GraphicsWindowX11::init()
useCursor(_traits->useCursor);
XSelectInput( _display, _window, ExposureMask | StructureNotifyMask |
KeyPressMask | KeyReleaseMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
_deleteWindow = XInternAtom (_display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(_display, _window, &_deleteWindow, 1);
XFlush( _display );
XSync( _display, 0 );
@@ -521,8 +528,13 @@ void GraphicsWindowX11::init()
//osg::notify(osg::NOTICE)<<"After sync apply.x = "<<watt.x<<" watt.y="<<watt.y<<" width="<<watt.width<<" height="<<watt.height<<std::endl;
_deleteWindow = XInternAtom (_display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(_display, _window, &_deleteWindow, True);
XSelectInput( _eventDisplay, _window, ExposureMask | StructureNotifyMask |
KeyPressMask | KeyReleaseMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
XFlush( _eventDisplay );
XSync( _eventDisplay, 0 );
_valid = true;
_initialized = true;
@@ -584,15 +596,26 @@ void GraphicsWindowX11::closeImplementation()
{
// osg::notify(osg::NOTICE)<<"Closing GraphicsWindowX11"<<std::endl;
if (_display && _window)
if (_eventDisplay)
{
glXDestroyContext(_display, _glxContext );
XDestroyWindow(_display, _window);
XCloseDisplay( _eventDisplay );
_eventDisplay = 0;
}
if (_display)
{
if (_glxContext)
{
glXDestroyContext(_display, _glxContext );
}
if (_window)
{
XDestroyWindow(_display, _window);
}
XFlush( _display );
XSync( _display,0 );
}
_window = 0;
@@ -605,13 +628,13 @@ void GraphicsWindowX11::closeImplementation()
_visualInfo = 0;
}
if (_display)
{
XCloseDisplay( _display );
_display = 0;
}
_initialized = false;
_realized = false;
_valid = false;
@@ -624,12 +647,32 @@ void GraphicsWindowX11::swapBuffersImplementation()
// osg::notify(osg::NOTICE)<<"swapBuffersImplementation "<<this<<" "<<OpenThreads::Thread::CurrentThread()<<std::endl;
glXSwapBuffers(_display, _window);
while( XPending(_display) )
{
XEvent ev;
XNextEvent( _display, &ev );
switch( ev.type )
{
case ClientMessage:
{
if (static_cast<Atom>(ev.xclient.data.l[0]) == _deleteWindow)
{
osg::notify(osg::INFO)<<"DeleteWindow event recieved"<<std::endl;
getEventQueue()->closeWindow();
}
}
}
}
}
void GraphicsWindowX11::checkEvents()
{
if (!_realized) return;
Display* display = _eventDisplay;
double baseTime = _timeOfLastCheckEvents;
double eventTime = baseTime;
double resizeTime = eventTime;
@@ -645,18 +688,19 @@ void GraphicsWindowX11::checkEvents()
Time firstEventTime = 0;
// osg::notify(osg::NOTICE)<<"Check events"<<std::endl;
while( XPending(_display) )
while( XPending(display) )
{
XEvent ev;
XNextEvent( _display, &ev );
XNextEvent( display, &ev );
switch( ev.type )
{
case ClientMessage:
{
osg::notify(osg::NOTICE)<<"ClientMessage event recieved"<<std::endl;
if (static_cast<Atom>(ev.xclient.data.l[0]) == _deleteWindow)
{
osg::notify(osg::INFO)<<"DeleteWindow event recieved"<<std::endl;
osg::notify(osg::NOTICE)<<"DeleteWindow event recieved"<<std::endl;
destroyWindowRequested = true;
getEventQueue()->closeWindow(eventTime);
}
@@ -678,7 +722,7 @@ void GraphicsWindowX11::checkEvents()
break;
case DestroyNotify :
osg::notify(osg::INFO)<<"DestroyNotify event recieved"<<std::endl;
osg::notify(osg::NOTICE)<<"DestroyNotify event recieved"<<std::endl;
_realized = false;
_valid = false;
break;
@@ -708,7 +752,7 @@ void GraphicsWindowX11::checkEvents()
osg::notify(osg::INFO)<<"MapNotify"<<std::endl;
XWindowAttributes watt;
do
XGetWindowAttributes(_display, _window, &watt );
XGetWindowAttributes(display, _window, &watt );
while( watt.map_state != IsViewable );
osg::notify(osg::INFO)<<"MapNotify x="<<watt.x<<" y="<<watt.y<<" width="<<watt.width<<", height="<<watt.height<<std::endl;
@@ -750,25 +794,25 @@ void GraphicsWindowX11::checkEvents()
int screenOrigin_x = 0;
int screenOrigin_y = 0;
int i;
for(i= 0; i < ScreenCount(_display); i++ )
for(i= 0; i < ScreenCount(display); i++ )
{
if( XQueryPointer( _display, RootWindow(_display, i),
if( XQueryPointer( display, RootWindow(display, i),
&root, &win, &rx, &ry, &wx, &wy, &buttons) )
{
break;
}
screenOrigin_x += DisplayWidth(_display, i);
screenOrigin_x += DisplayWidth(display, i);
}
for(i= 0; i < static_cast<int>(_traits->screenNum); i++ )
{
screenOrigin_x -= DisplayWidth(_display, i);
screenOrigin_x -= DisplayWidth(display, i);
}
int dest_x_return, dest_y_return;
Window child_return;
XTranslateCoordinates(_display, _window, _parent, 0, 0, &dest_x_return, &dest_y_return, &child_return);
XTranslateCoordinates(display, _window, _parent, 0, 0, &dest_x_return, &dest_y_return, &child_return);
wx += (screenOrigin_x - dest_x_return);
wy += (screenOrigin_y - dest_y_return);
@@ -889,8 +933,8 @@ void GraphicsWindowX11::checkEvents()
void GraphicsWindowX11::grabFocus()
{
XSetInputFocus( _display, _window, RevertToNone, CurrentTime );
XFlush(_display); XSync(_display,0);
XSetInputFocus( _eventDisplay, _window, RevertToNone, CurrentTime );
XFlush(_eventDisplay); XSync(_eventDisplay,0);
}
void GraphicsWindowX11::grabFocusIfPointerInWindow()
@@ -899,10 +943,18 @@ void GraphicsWindowX11::grabFocusIfPointerInWindow()
int wx, wy, rx, ry;
unsigned int buttons;
if( XQueryPointer( _display, _window,
if( XQueryPointer( _eventDisplay, _window,
&root, &win, &rx, &ry, &wx, &wy, &buttons))
{
#if 0
if (wx>=0 && wx<_traits->width &&
wy>=0 && wy<_traits->height)
{
grabFocus();
}
#else
grabFocus();
#endif
}
}
@@ -952,7 +1004,7 @@ void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, unsigned i
keySymbol = keybuf[0];
KeySym ks = XKeycodeToKeysym( _display, keyevent.keycode, 0 );
KeySym ks = XKeycodeToKeysym( _eventDisplay, keyevent.keycode, 0 );
int remappedKey = remapX11Key(ks);
if (remappedKey & 0xff00)
{
@@ -970,14 +1022,14 @@ void GraphicsWindowX11::adaptKey(XKeyEvent& keyevent, int& keySymbol, unsigned i
void GraphicsWindowX11::requestWarpPointer(float x,float y)
{
XWarpPointer( _display,
XWarpPointer( _eventDisplay,
None,
_window,
0, 0, 0, 0,
static_cast<int>(x), static_cast<int>(y) );
XFlush(_display);
XSync(_display, 0);
XFlush(_eventDisplay);
XSync(_eventDisplay, 0);
getEventQueue()->mouseWarped(x,y);
}
@@ -1021,7 +1073,7 @@ struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSyste
{
XSetErrorHandler(X11ErrorHandling);
#if 1
#if 0
if (XInitThreads() == 0)
{
osg::notify(osg::NOTICE) << "Error: XInitThreads() failed. Aborting." << std::endl;