From Stephan Huber, "New features:

+ Multi-display-support
+ automatic hiding of the menubar/dock if one of the windows intersects
the menubar/dock

Bugfixes:
+ event-handling was done by the first opened window, other windows did
not receive events -- fixed
+ mouse-coordinates were absolute, now they are relative to the window.

known bugs:
+ windows with decoration and in fullscreen-size are moved by the system
a little bit, so that the titlebar is accessible/visible. So if you want
real fullscreen-windows, don't decorate the window :)

I updated the XCode-project-file so all ported examples are linked
against osgViewer."
This commit is contained in:
Robert Osfield 2007-01-12 21:33:19 +00:00
parent 694b304c00
commit 785fd5c0d9
3 changed files with 520 additions and 763 deletions

File diff suppressed because it is too large Load Diff

View File

@ -82,6 +82,11 @@ class GraphicsWindowCarbon : public osgViewer::GraphicsWindow
void requestClose() { _closeRequested = true; } void requestClose() { _closeRequested = true; }
virtual void resizedImplementation(int x, int y, int width, int height); virtual void resizedImplementation(int x, int y, int width, int height);
WindowRef getNativeWindowRef() { return _window; }
bool handleMouseEvent(EventRef theEvent);
bool handleKeyboardEvent(EventRef theEvent);
protected: protected:
@ -99,11 +104,7 @@ class GraphicsWindowCarbon : public osgViewer::GraphicsWindow
AGLContext _context; AGLContext _context;
AGLPixelFormat _pixelFormat; AGLPixelFormat _pixelFormat;
private: private:
void handleMouseEvent(EventRef theEvent);
void handleKeyboardEvent(EventRef theEvent);
bool _closeRequested; bool _closeRequested;
}; };

View File

@ -12,7 +12,7 @@
*/ */
#ifdef __APPLE__ #ifdef __APPLE__
#include <osg/observer_ptr>
#include <osgViewer/GraphicsWindowCarbon> #include <osgViewer/GraphicsWindowCarbon>
#include <Carbon/Carbon.h> #include <Carbon/Carbon.h>
#include <OpenGL/OpenGL.h> #include <OpenGL/OpenGL.h>
@ -21,13 +21,14 @@ using namespace osgViewer;
// Carbon-Eventhandler to handle the click in the close-widget and the resize of windows // Carbon-Eventhandler to handle the click in the close-widget and the resize of windows
static pascal OSStatus GraphicsWindowEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData) static pascal OSStatus GraphicsWindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void* userData)
{ {
WindowRef window; WindowRef window;
Rect bounds; Rect bounds;
UInt32 whatHappened;
OSStatus result = eventNotHandledErr; /* report failure by default */ OSStatus result = eventNotHandledErr; /* report failure by default */
result = CallNextEventHandler (nextHandler, event);
GraphicsWindowCarbon* w = (GraphicsWindowCarbon*)userData; GraphicsWindowCarbon* w = (GraphicsWindowCarbon*)userData;
if (!w) if (!w)
@ -35,41 +36,53 @@ static pascal OSStatus GraphicsWindowEventHandler(EventHandlerCallRef myHandler,
GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL,
sizeof(window), NULL, &window); sizeof(window), NULL, &window);
whatHappened = GetEventKind(event); switch(GetEventClass(event))
{
case kEventClassTablet:
switch (whatHappened) case kEventClassMouse:
{ if (w->handleMouseEvent(event))
case kEventWindowBoundsChanging:
// left the code for live-resizing, but it is not used, because of window-refreshing issues...
GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &bounds );
w->resized(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top);
w->getEventQueue()->windowResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, w->getEventQueue()->getTime());
w->requestRedraw();
result = noErr; result = noErr;
break; break;
case kEventClassKeyboard:
if (w->handleKeyboardEvent(event))
result = noErr;
break;
case kEventClassWindow: {
switch (GetEventKind(event))
{
case kEventWindowBoundsChanging:
// left the code for live-resizing, but it is not used, because of window-refreshing issues...
GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &bounds );
w->resized(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top);
w->getEventQueue()->windowResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, w->getEventQueue()->getTime());
w->requestRedraw();
result = noErr;
break;
case kEventWindowBoundsChanged:
InvalWindowRect(window, GetWindowPortBounds(window, &bounds));
GetWindowBounds(window, kWindowContentRgn, &bounds);
w->resized(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top);
w->getEventQueue()->windowResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, w->getEventQueue()->getTime());
result = noErr;
break;
case kEventWindowBoundsChanged: case kEventWindowClosed:
InvalWindowRect(window, GetWindowPortBounds(window, &bounds)); w->requestClose();
GetWindowBounds(window, kWindowContentRgn, &bounds); break;
w->resized(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top);
w->getEventQueue()->windowResize(bounds.left, bounds.top, bounds.right - bounds.left, bounds.bottom - bounds.top, w->getEventQueue()->getTime()); default:
result = noErr; break;
break; }
}
case kEventWindowClosed: default:
w->requestClose(); break;
break; }
default:
/* If nobody handled the event, it gets propagated to the */
/* application-level handler. */
break;
}
return result; return result;
} }
@ -216,6 +229,9 @@ static AGLPixelFormat createPixelFormat(osg::GraphicsContext::Traits* traits) {
return aglChoosePixelFormat(NULL, 0, &(attributes.front())); return aglChoosePixelFormat(NULL, 0, &(attributes.front()));
} }
#pragma mark * * * GraphicsContextCarbon * * *
/** This is the class we need to create for pbuffers, note its not a GraphicsWindow as it won't need any of the event handling and window mapping facilities.*/ /** This is the class we need to create for pbuffers, note its not a GraphicsWindow as it won't need any of the event handling and window mapping facilities.*/
class GraphicsContextCarbon : public osg::GraphicsContext class GraphicsContextCarbon : public osg::GraphicsContext
{ {
@ -267,8 +283,206 @@ class GraphicsContextCarbon : public osg::GraphicsContext
}; };
#pragma mark * * * OSXWindowingSystemInterface * * *
class MenubarController : public osg::Referenced
{
public:
MenubarController() : osg::Referenced(), _list(), _menubarShown(false) {
// the following code will query the system for the available ect on the main-display (typically the displaying showing the menubar + the dock
GDHandle mainScreenDevice;
DMGetGDeviceByDisplayID((DisplayIDType) CGMainDisplayID(), &mainScreenDevice, true);
GetAvailableWindowPositioningBounds (mainScreenDevice, &_availRect);
// now we need the rect of the main-display including the menubar and the dock
_mainScreenBounds = CGDisplayBounds( CGMainDisplayID() );
// hide the menubar initially
SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
}
static MenubarController* instance();
void attachWindow(GraphicsWindowCarbon* win);
void update();
void detachWindow(GraphicsWindowCarbon* win);
private:
typedef std::list< osg::observer_ptr< GraphicsWindowCarbon > > WindowList;
WindowList _list;
bool _menubarShown;
Rect _availRect;
CGRect _mainScreenBounds;
};
MenubarController* MenubarController::instance()
{
static osg::ref_ptr<MenubarController> s_menubar_controller = new MenubarController();
return s_menubar_controller.get();
} }
void MenubarController::attachWindow(GraphicsWindowCarbon* win)
{
_list.push_back(win);
update();
}
void MenubarController::detachWindow(GraphicsWindowCarbon* win)
{
for(WindowList::iterator i = _list.begin(); i != _list.end(); ) {
if ((*i).get() == win)
i = _list.erase(i);
else
++i;
}
update();
}
// iterate through all open windows and check, if they intersect the area occupied by the menubar/dock, and if so, hide the menubar/dock
void MenubarController::update()
{
OSErr error(noErr);
unsigned int windowsCoveringMenubarArea = 0;
unsigned int windowsIntersectingMainScreen = 0;
for(WindowList::iterator i = _list.begin(); i != _list.end(); ) {
if ((*i).valid()) {
GraphicsWindowCarbon* w = (*i).get();
Rect windowBounds;
error = GetWindowBounds(w->getNativeWindowRef(), kWindowStructureRgn, &windowBounds);
bool intersect = !( (_mainScreenBounds.origin.x > windowBounds.right) ||
(_mainScreenBounds.origin.x + _mainScreenBounds.size.width < windowBounds.left) ||
(_mainScreenBounds.origin.y > windowBounds.bottom) ||
(_mainScreenBounds.origin.y + _mainScreenBounds.size.height < windowBounds.top));
if (intersect && !error)
{
++windowsIntersectingMainScreen;
// the window intersects the main-screen, does it intersect with the menubar/dock?
if (((_availRect.top > _mainScreenBounds.origin.y) && (_availRect.top > windowBounds.top)) ||
((_availRect.left > _mainScreenBounds.origin.x) && (_availRect.left > windowBounds.left)) ||
((_availRect.right < _mainScreenBounds.origin.x + _mainScreenBounds.size.width) && (_availRect.right < windowBounds.right)) ||
((_availRect.bottom < _mainScreenBounds.origin.y + _mainScreenBounds.size.height) && (_availRect.bottom < windowBounds.bottom) ))
{
++windowsCoveringMenubarArea;
}
}
++i;
}
else
i= _list.erase(i);
}
// see http://developer.apple.com/technotes/tn2002/tn2062.html for hiding the dock+menubar
if (windowsCoveringMenubarArea && _menubarShown)
error = SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
if (!windowsCoveringMenubarArea && !_menubarShown)
error = SetSystemUIMode(kUIModeNormal, 0);
_menubarShown = !windowsCoveringMenubarArea;
// osg::notify(osg::DEBUG_INFO) << "MenubarController:: " << windowsCoveringMenubarArea << " windows covering the menubar/dock area, " << windowsIntersectingMainScreen << " intersecting mainscreen" << std::endl;
}
#pragma mark * * * OSXWindowingSystemInterface * * *
struct OSXCarbonWindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface
{
/** ctor, get a list of all attached displays */
OSXCarbonWindowingSystemInterface() :
_displayCount(0),
_displayIds(NULL)
{
if( CGGetActiveDisplayList( 0, NULL, &_displayCount ) != CGDisplayNoErr )
osg::notify(osg::WARN) << "OSXCarbonWindowingSystemInterface: could not get # of screens" << std::endl;
_displayIds = new CGDirectDisplayID[_displayCount];
if( CGGetActiveDisplayList( _displayCount, _displayIds, &_displayCount ) != CGDisplayNoErr )
osg::notify(osg::WARN) << "OSXCarbonWindowingSystemInterface: CGGetActiveDisplayList failed" << std::endl;
// register application event handler and AppleEventHandler to get quit-events:
static const EventTypeSpec menueventSpec = {kEventClassCommand, kEventCommandProcess};
OSErr status = InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(ApplicationEventHandler), 1, &menueventSpec, 0, NULL);
status = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false);
}
/** dtor */
~OSXCarbonWindowingSystemInterface() {
if (_displayIds)
delete[] _displayIds;
_displayIds = NULL;
}
/** @return a CGDirectDisplayID for a ScreenIdentifier */
inline CGDirectDisplayID getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) {
return _displayIds[si.screenNum];
}
/** @return count of attached screens */
virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si)
{
return _displayCount;
}
/** returns the resolution of a specific display */
virtual void getScreenResolution(const osg::GraphicsContext::ScreenIdentifier& si, unsigned int& width, unsigned int& height)
{
CGDirectDisplayID id = getDisplayID(si);
width = CGDisplayPixelsWide(id);
height = CGDisplayPixelsHigh(id);
}
/** return the top left coord of a specific screen in global screen space */
void getScreenTopLeft(const osg::GraphicsContext::ScreenIdentifier& si, int& x, int& y) {
CGRect bounds = CGDisplayBounds( getDisplayID(si) );
x = bounds.origin.x;
y = bounds.origin.y;
// osg::notify(osg::DEBUG_INFO) << "topleft of screen " << si.screenNum <<" " << bounds.origin.x << "/" << bounds.origin.y << std::endl;
}
virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits)
{
if (traits->pbuffer)
{
osg::ref_ptr<osgViewer::GraphicsContextCarbon> pbuffer = new GraphicsContextCarbon(traits);
if (pbuffer->valid()) return pbuffer.release();
else return 0;
}
else
{
osg::ref_ptr<osgViewer::GraphicsWindowCarbon> window = new GraphicsWindowCarbon(traits);
if (window->valid()) return window.release();
else return 0;
}
}
private:
CGDisplayCount _displayCount;
CGDirectDisplayID* _displayIds;
};
}
#pragma mark * * * GraphicsWindowCarbon * * *
void GraphicsWindowCarbon::setWindowDecoration(bool flag) void GraphicsWindowCarbon::setWindowDecoration(bool flag)
{ {
_useWindowDecoration = flag; _useWindowDecoration = flag;
@ -297,31 +511,62 @@ bool GraphicsWindowCarbon::realizeImplementation()
setWindowDecoration(_traits->windowDecoration); setWindowDecoration(_traits->windowDecoration);
// move the window to the right screen
OSXCarbonWindowingSystemInterface* wsi = dynamic_cast<OSXCarbonWindowingSystemInterface*>(osg::GraphicsContext::getWindowingSystemInterface());
int screenLeft(0), screenTop(0);
if (wsi) {
wsi->getScreenTopLeft((*_traits), screenLeft, screenTop);
_traits->y += screenTop;
_traits->x += screenLeft;
}
// create the window // create the window
Rect bounds = {_traits->y, _traits->x, _traits->y + _traits->height, _traits->x + _traits->width}; Rect bounds = {_traits->y, _traits->x, _traits->y + _traits->height, _traits->x + _traits->width};
OSStatus err = 0; OSStatus err = 0;
WindowAttributes attr; WindowAttributes attr;
if (_useWindowDecoration) if (_useWindowDecoration)
{
if (_traits->supportsResize) if (_traits->supportsResize)
attr = (kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute); attr = (kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute);
else else
attr = (kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute) & ~kWindowResizableAttribute; attr = (kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute) & ~kWindowResizableAttribute;
err = CreateNewWindow(kDocumentWindowClass, attr, &bounds, &_window);
}
else { else {
attr = kWindowStandardHandlerAttribute; attr = kWindowStandardHandlerAttribute;
if (_traits->supportsResize) if (_traits->supportsResize)
attr |= kWindowResizableAttribute; attr |= kWindowResizableAttribute;
err = CreateNewWindow(kSimpleWindowClass, attr, &bounds, &_window);
} }
err = CreateNewWindow(kDocumentWindowClass, attr, &bounds, &_window);
if (err) { if (err) {
osg::notify(osg::WARN) << "GraphicsWindowCarbon::realizeImplementation() failed creating a window: " << err << std::endl; osg::notify(osg::WARN) << "GraphicsWindowCarbon::realizeImplementation() failed creating a window: " << err << std::endl;
return false; return false;
} }
// register window event handler to receive resize-events // register window event handler to receive resize-events
EventTypeSpec windEventList[] = {{ kEventClassWindow, kEventWindowBoundsChanged},{ kEventClassWindow, kEventWindowClosed}}; EventTypeSpec windEventList[] = {
InstallWindowEventHandler(_window, NewEventHandlerUPP(GraphicsWindowEventHandler), 2, windEventList, this, NULL); { kEventClassWindow, kEventWindowBoundsChanged},
{ kEventClassWindow, kEventWindowClosed},
{kEventClassMouse, kEventMouseDown},
{kEventClassMouse, kEventMouseUp},
{kEventClassMouse, kEventMouseMoved},
{kEventClassMouse, kEventMouseDragged},
{kEventClassMouse, kEventMouseWheelMoved},
{kEventClassKeyboard, kEventRawKeyDown},
{kEventClassKeyboard, kEventRawKeyRepeat},
{kEventClassKeyboard, kEventRawKeyUp},
{kEventClassKeyboard, kEventRawKeyModifiersChanged},
{kEventClassKeyboard, kEventHotKeyPressed},
{kEventClassKeyboard, kEventHotKeyReleased},
};
InstallWindowEventHandler(_window, NewEventHandlerUPP(GraphicsWindowEventHandler), GetEventTypeCount(windEventList), windEventList, this, NULL);
// set the window title // set the window title
if (!_traits->windowName.empty()) { if (!_traits->windowName.empty()) {
@ -358,6 +603,7 @@ bool GraphicsWindowCarbon::realizeImplementation()
aglSetInteger (_context, AGL_SWAP_INTERVAL, &swap); aglSetInteger (_context, AGL_SWAP_INTERVAL, &swap);
} }
MenubarController::instance()->attachWindow(this);
_realized = true; _realized = true;
return _realized; return _realized;
@ -391,6 +637,8 @@ void GraphicsWindowCarbon::closeImplementation()
_valid = false; _valid = false;
_realized = false; _realized = false;
MenubarController::instance()->detachWindow(this);
if (_pixelFormat) if (_pixelFormat)
{ {
aglDestroyPixelFormat(_pixelFormat); aglDestroyPixelFormat(_pixelFormat);
@ -420,36 +668,41 @@ void GraphicsWindowCarbon::swapBuffersImplementation()
void GraphicsWindowCarbon::resizedImplementation(int x, int y, int width, int height) void GraphicsWindowCarbon::resizedImplementation(int x, int y, int width, int height)
{ {
GraphicsContext::resizedImplementation(x, y, width, height);
aglUpdateContext(_context); aglUpdateContext(_context);
MenubarController::instance()->update();
} }
void GraphicsWindowCarbon::handleMouseEvent(EventRef theEvent) bool GraphicsWindowCarbon::handleMouseEvent(EventRef theEvent)
{ {
static unsigned int lastEmulatedMouseButton = 0;
// mouse down event // mouse down event
Point wheresMyMouse; Point wheresMyMouse;
GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(wheresMyMouse), NULL, &wheresMyMouse); GetEventParameter (theEvent, kEventParamWindowMouseLocation, typeQDPoint, NULL, sizeof(wheresMyMouse), NULL, &wheresMyMouse);
Point wheresMyMouseGlobal;
GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(wheresMyMouse), NULL, &wheresMyMouseGlobal);
EventMouseButton mouseButton = 0; EventMouseButton mouseButton = 0;
GetEventParameter (theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(mouseButton), NULL, &mouseButton); GetEventParameter (theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(mouseButton), NULL, &mouseButton);
UInt32 modifierKeys;
GetEventParameter (theEvent,kEventParamKeyModifiers,typeUInt32, NULL,sizeof(modifierKeys), NULL,&modifierKeys);
WindowRef win; WindowRef win;
int fwres = FindWindow(wheresMyMouse, &win); int fwres = FindWindow(wheresMyMouseGlobal, &win);
if ((fwres != inContent) && (fwres > 0) && (mouseButton >= 1))
if ((fwres == inMenuBar) && (mouseButton >= 1)) {
MenuSelect(wheresMyMouse);
HiliteMenu(0);
return;
}
else if ((fwres != inContent) && (fwres > 0) && (mouseButton >= 1))
{ {
return; return false;
} }
else else
{ {
// swap right and middle buttons so that middle button is 2, right button is 3. // swap right and middle buttons so that middle button is 2, right button is 3.
if (mouseButton==3) mouseButton = 2; if (mouseButton==3) mouseButton = 2;
else if (mouseButton==2) mouseButton = 3; else if (mouseButton==2) mouseButton = 3;
@ -492,6 +745,21 @@ void GraphicsWindowCarbon::handleMouseEvent(EventRef theEvent)
float mx =wheresMyMouse.h; float mx =wheresMyMouse.h;
float my =wheresMyMouse.v; float my =wheresMyMouse.v;
transformMouseXY(mx, my); transformMouseXY(mx, my);
lastEmulatedMouseButton = 0;
if (mouseButton == 1)
{
if( modifierKeys & cmdKey )
{
mouseButton = lastEmulatedMouseButton = 3;
}
else if( modifierKeys & optionKey )
{
mouseButton = lastEmulatedMouseButton = 2;
}
}
getEventQueue()->mouseButtonPress(mx, my, mouseButton); getEventQueue()->mouseButtonPress(mx, my, mouseButton);
} }
break; break;
@ -500,7 +768,13 @@ void GraphicsWindowCarbon::handleMouseEvent(EventRef theEvent)
float mx =wheresMyMouse.h; float mx =wheresMyMouse.h;
float my =wheresMyMouse.v; float my =wheresMyMouse.v;
transformMouseXY(mx, my); transformMouseXY(mx, my);
getEventQueue()->mouseButtonRelease(mx, my, mouseButton); if (lastEmulatedMouseButton > 0) {
getEventQueue()->mouseButtonRelease(mx, my, lastEmulatedMouseButton);
lastEmulatedMouseButton = 0;
}
else {
getEventQueue()->mouseButtonRelease(mx, my, mouseButton);
}
} }
break; break;
@ -573,14 +847,16 @@ void GraphicsWindowCarbon::handleMouseEvent(EventRef theEvent)
break; break;
default: default:
return; return false;
} }
} }
return true;
} }
void GraphicsWindowCarbon::handleKeyboardEvent(EventRef theEvent) bool GraphicsWindowCarbon::handleKeyboardEvent(EventRef theEvent)
{ {
@ -625,8 +901,8 @@ void GraphicsWindowCarbon::handleKeyboardEvent(EventRef theEvent)
UInt32 dataSize; UInt32 dataSize;
/* jbw check return status so that we don't allocate a huge array */ /* jbw check return status so that we don't allocate a huge array */
status = GetEventParameter( theEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0, &dataSize, NULL ); status = GetEventParameter( theEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0, &dataSize, NULL );
if (status != noErr) return; if (status != noErr) return false;
if (dataSize<=1) return; if (dataSize<=1) return false;
UniChar* uniChars = new UniChar[dataSize+1]; UniChar* uniChars = new UniChar[dataSize+1];
GetEventParameter( theEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, dataSize, NULL, (void*)uniChars ); GetEventParameter( theEvent, kEventParamKeyUnicodes, typeUnicodeText, NULL, dataSize, NULL, (void*)uniChars );
@ -657,7 +933,7 @@ void GraphicsWindowCarbon::handleKeyboardEvent(EventRef theEvent)
delete[] uniChars; delete[] uniChars;
return; return true;
} }
@ -672,15 +948,26 @@ void GraphicsWindowCarbon::checkEvents()
{ {
switch(GetEventClass(theEvent)) switch(GetEventClass(theEvent))
{ {
case kEventClassTablet: case kEventClassMouse:
case kEventClassMouse: {
handleMouseEvent(theEvent); // handle the menubar
break; Point wheresMyMouse;
GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(wheresMyMouse), NULL, &wheresMyMouse);
case kEventClassKeyboard:
handleKeyboardEvent(theEvent); EventMouseButton mouseButton = 0;
break; GetEventParameter (theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(mouseButton), NULL, &mouseButton);
WindowRef win;
int fwres = FindWindow(wheresMyMouse, &win);
if ((fwres == inMenuBar) && (mouseButton >= 1)) {
MenuSelect(wheresMyMouse);
HiliteMenu(0);
return;
}
break;
}
case kEventClassApplication: case kEventClassApplication:
switch (GetEventKind(theEvent)) { switch (GetEventKind(theEvent)) {
case kEventAppQuit: case kEventAppQuit:
@ -724,6 +1011,7 @@ void GraphicsWindowCarbon::grabFocus()
void GraphicsWindowCarbon::grabFocusIfPointerInWindow() void GraphicsWindowCarbon::grabFocusIfPointerInWindow()
{ {
// TODO: implement // TODO: implement
osg::notify(osg::ALWAYS) << "GraphicsWindowCarbon::grabFocusIfPointerInWindow" << std::endl;
} }
@ -740,68 +1028,6 @@ void GraphicsWindowCarbon::transformMouseXY(float& x, float& y)
struct OSXCarbonWindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface
{
OSXCarbonWindowingSystemInterface() :
_displayCount(0),
_displayIds(NULL)
{
if( CGGetActiveDisplayList( 0, NULL, &_displayCount ) != CGDisplayNoErr )
osg::notify(osg::WARN) << "OSXCarbonWindowingSystemInterface: could not get # of screens" << std::endl;
_displayIds = new CGDirectDisplayID[_displayCount];
if( CGGetActiveDisplayList( _displayCount, _displayIds, &_displayCount ) != CGDisplayNoErr )
osg::notify(osg::WARN) << "OSXCarbonWindowingSystemInterface: CGGetActiveDisplayList failed" << std::endl;
// register application event handler and AppleEventHandler to get quit-events:
static const EventTypeSpec menueventSpec = {kEventClassCommand, kEventCommandProcess};
OSErr status = InstallEventHandler(GetApplicationEventTarget(), NewEventHandlerUPP(ApplicationEventHandler), 1, &menueventSpec, 0, NULL);
status = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(QuitAppleEventHandler), 0, false);
}
~OSXCarbonWindowingSystemInterface() {
if (_displayIds)
delete[] _displayIds;
_displayIds = NULL;
}
inline CGDirectDisplayID getDisplayID(const osg::GraphicsContext::ScreenIdentifier& si) {
return _displayIds[si.screenNum];
}
virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si)
{
return _displayCount;
}
virtual void getScreenResolution(const osg::GraphicsContext::ScreenIdentifier& si, unsigned int& width, unsigned int& height)
{
CGDirectDisplayID id = getDisplayID(si);
width = CGDisplayPixelsWide(id);
height = CGDisplayPixelsHigh(id);
}
virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits)
{
if (traits->pbuffer)
{
osg::ref_ptr<osgViewer::GraphicsContextCarbon> pbuffer = new GraphicsContextCarbon(traits);
if (pbuffer->valid()) return pbuffer.release();
else return 0;
}
else
{
osg::ref_ptr<osgViewer::GraphicsWindowCarbon> window = new GraphicsWindowCarbon(traits);
if (window->valid()) return window.release();
else return 0;
}
}
private:
CGDisplayCount _displayCount;
CGDirectDisplayID* _displayIds;
};
@ -809,7 +1035,7 @@ struct RegisterWindowingSystemInterfaceProxy
{ {
RegisterWindowingSystemInterfaceProxy() RegisterWindowingSystemInterfaceProxy()
{ {
osg::GraphicsContext::setWindowingSystemInterface(new OSXCarbonWindowingSystemInterface); osg::GraphicsContext::setWindowingSystemInterface(new osgViewer::OSXCarbonWindowingSystemInterface());
} }
~RegisterWindowingSystemInterfaceProxy() ~RegisterWindowingSystemInterfaceProxy()