blob: ee1aa3f87835c8f2a403b367856a330cc5e89a92 [file] [log] [blame]
/*
* Copyright 2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "plugin/mac/graphics_utils_mac.h"
namespace o3d {
// Slide a window to a different rect, asynchronously, over a period of time.
void SlideWindowToRect(WindowRef the_window,
CGRect destination_rect,
double transition_duration_seconds) {
TransitionWindowOptions options = {0, transition_duration_seconds,
NULL, NULL};
TransitionWindowWithOptions(the_window,
kWindowSlideTransitionEffect,
kWindowMoveTransitionAction,
&destination_rect, true, &options);
}
// Sets a Carbon window to a custom window level, by creating a new window
// group at that level and adding the window to the group.
void SetWindowLevel(WindowRef window, int level) {
WindowGroupRef wGroup = NULL;
WindowGroupAttributes attrs = 0;
CreateWindowGroup(attrs, &wGroup);
SetWindowGroupLevel(wGroup, level);
SetWindowGroup(window, wGroup);
}
// Given a WindowRef and an AGLContext, make the context draw in that window.
// Return Value: true if the window is successfully set, false otherwise.
bool SetWindowForAGLContext(AGLContext context, WindowRef window) {
return (IsMacOSTenFiveOrHigher()) ?
aglSetWindowRef(context, window) :
aglSetDrawable(context, GetWindowPort(window));
}
// Returns whether OS is 10.5 (Leopard) or higher.
bool IsMacOSTenFiveOrHigher() {
static bool isCached = false, result = false;
if (!isCached) {
SInt32 major = 0;
SInt32 minor = 0;
// These selectors don't exist pre 10.4 but as we check the error
// the function will correctly return NO which is the right answer.
result = ((::Gestalt(gestaltSystemVersionMajor, &major) == noErr) &&
(::Gestalt(gestaltSystemVersionMinor, &minor) == noErr) &&
((major > 10) || (major == 10 && minor >= 5)));
isCached = true;
}
return result;
}
// Returns whether OS is 10.6 (Snow Leopard) or higher.
bool IsMacOSTenSixOrHigher() {
static bool isCached = false, result = false;
if (!isCached) {
SInt32 major = 0;
SInt32 minor = 0;
// These selectors don't exist pre 10.4 but as we check the error
// the function will correctly return NO which is the right answer.
result = ((::Gestalt(gestaltSystemVersionMajor, &major) == noErr) &&
(::Gestalt(gestaltSystemVersionMinor, &minor) == noErr) &&
((major > 10) || (major == 10 && minor >= 6)));
isCached = true;
}
return result;
}
Rect CGRect2Rect(const CGRect &inRect) {
Rect outRect;
outRect.left = inRect.origin.x;
outRect.top = inRect.origin.y;
outRect.right = inRect.origin.x + inRect.size.width;
outRect.bottom = inRect.origin.y + inRect.size.height;
return outRect;
}
CGRect Rect2CGRect(const Rect &inRect) {
CGRect outRect;
outRect.origin.x = inRect.left;
outRect.origin.y = inRect.top;
outRect.size.width = inRect.right - inRect.left;
outRect.size.height = inRect.bottom - inRect.top;
return outRect;
}
// Paint a round rect, with the corner radius you specify, either filled or
// stroked.
void PaintRoundedCGRect(CGContextRef context,
CGRect rect,
float radius,
bool fill) {
CGFloat lx = CGRectGetMinX(rect);
CGFloat cx = CGRectGetMidX(rect);
CGFloat rx = CGRectGetMaxX(rect);
CGFloat by = CGRectGetMinY(rect);
CGFloat cy = CGRectGetMidY(rect);
CGFloat ty = CGRectGetMaxY(rect);
CGContextBeginPath(context);
CGContextMoveToPoint(context, lx, cy);
CGContextAddArcToPoint(context, lx, by, cx, by, radius);
CGContextAddArcToPoint(context, rx, by, rx, cy, radius);
CGContextAddArcToPoint(context, rx, ty, cx, ty, radius);
CGContextAddArcToPoint(context, lx, ty, lx, cy, radius);
CGContextClosePath(context);
if (fill)
CGContextFillPath(context);
else
CGContextStrokePath(context);
}
} // namespace o3d