* EventInfo.cs:

* AglContext.cs:
* MacOSKeyMap.cs:
* CarbonInput.cs:
* Application.cs:
* MacOSFactory.cs:
* CarbonGLNative.cs:
* CarbonWindowInfo.cs:
* MacOSGraphicsMode.cs:
* QuartzDisplayDeviceDriver.cs: Normalized code formatting.
This commit is contained in:
the_fiddler 2010-11-02 19:49:24 +00:00
parent bde71543f5
commit 7e344e2ac2
10 changed files with 882 additions and 949 deletions

View file

@ -23,41 +23,40 @@ namespace OpenTK.Platform.MacOS
using AGLContext = IntPtr; using AGLContext = IntPtr;
using AGLPbuffer = IntPtr; using AGLPbuffer = IntPtr;
class AglContext : DesktopGraphicsContext class AglContext : DesktopGraphicsContext
{ {
bool mVSync = false; bool mVSync = false;
// Todo: keep track of which display adapter was specified when the context was created. // Todo: keep track of which display adapter was specified when the context was created.
// IntPtr displayID; // IntPtr displayID;
GraphicsMode graphics_mode; GraphicsMode graphics_mode;
CarbonWindowInfo carbonWindow; CarbonWindowInfo carbonWindow;
IntPtr shareContextRef; IntPtr shareContextRef;
DisplayDevice device; DisplayDevice device;
bool mIsFullscreen = false; bool mIsFullscreen = false;
public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext) public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext)
{ {
Debug.Print("Context Type: {0}", shareContext); Debug.Print("Context Type: {0}", shareContext);
Debug.Print("Window info: {0}", window); Debug.Print("Window info: {0}", window);
this.graphics_mode = mode; this.graphics_mode = mode;
this.carbonWindow = (CarbonWindowInfo)window; this.carbonWindow = (CarbonWindowInfo)window;
if (shareContext is AglContext) if (shareContext is AglContext)
shareContextRef = ((AglContext)shareContext).Handle.Handle; shareContextRef = ((AglContext)shareContext).Handle.Handle;
if (shareContext is GraphicsContext) if (shareContext is GraphicsContext)
{ {
ContextHandle shareHandle = shareContext != null ? ContextHandle shareHandle = shareContext != null ? (shareContext as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
(shareContext as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
shareContextRef = shareHandle.Handle;
shareContextRef = shareHandle.Handle; }
}
if (shareContextRef == IntPtr.Zero)
if (shareContextRef == IntPtr.Zero) {
{ Debug.Print("No context sharing will take place.");
Debug.Print("No context sharing will take place."); }
}
CreateContext(mode, carbonWindow, shareContextRef, true); CreateContext(mode, carbonWindow, shareContextRef, true);
} }
@ -67,7 +66,7 @@ namespace OpenTK.Platform.MacOS
throw new ArgumentException("handle"); throw new ArgumentException("handle");
if (window == null) if (window == null)
throw new ArgumentNullException("window"); throw new ArgumentNullException("window");
Handle = handle; Handle = handle;
carbonWindow = (CarbonWindowInfo)window; carbonWindow = (CarbonWindowInfo)window;
} }
@ -76,37 +75,36 @@ namespace OpenTK.Platform.MacOS
private void AddPixelAttrib(List<int> aglAttributes, Agl.PixelFormatAttribute pixelFormatAttribute) private void AddPixelAttrib(List<int> aglAttributes, Agl.PixelFormatAttribute pixelFormatAttribute)
{ {
Debug.Print(pixelFormatAttribute.ToString()); Debug.Print(pixelFormatAttribute.ToString());
aglAttributes.Add((int)pixelFormatAttribute); aglAttributes.Add((int)pixelFormatAttribute);
} }
private void AddPixelAttrib(List<int> aglAttributes, Agl.PixelFormatAttribute pixelFormatAttribute, int value) private void AddPixelAttrib(List<int> aglAttributes, Agl.PixelFormatAttribute pixelFormatAttribute, int value)
{ {
Debug.Print("{0} : {1}", pixelFormatAttribute, value); Debug.Print("{0} : {1}", pixelFormatAttribute, value);
aglAttributes.Add((int)pixelFormatAttribute); aglAttributes.Add((int)pixelFormatAttribute);
aglAttributes.Add(value); aglAttributes.Add(value);
} }
void CreateContext(GraphicsMode mode, CarbonWindowInfo carbonWindow, void CreateContext(GraphicsMode mode, CarbonWindowInfo carbonWindow, IntPtr shareContextRef, bool fullscreen)
IntPtr shareContextRef, bool fullscreen)
{ {
List<int> aglAttributes = new List<int>(); List<int> aglAttributes = new List<int>();
Debug.Print("AGL pixel format attributes:"); Debug.Print("AGL pixel format attributes:");
Debug.Indent(); Debug.Indent();
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_RGBA); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_RGBA);
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_DOUBLEBUFFER); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_DOUBLEBUFFER);
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_RED_SIZE, mode.ColorFormat.Red); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_RED_SIZE, mode.ColorFormat.Red);
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_GREEN_SIZE, mode.ColorFormat.Green); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_GREEN_SIZE, mode.ColorFormat.Green);
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_BLUE_SIZE, mode.ColorFormat.Blue); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_BLUE_SIZE, mode.ColorFormat.Blue);
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ALPHA_SIZE, mode.ColorFormat.Alpha); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ALPHA_SIZE, mode.ColorFormat.Alpha);
if (mode.Depth > 0) if (mode.Depth > 0)
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_DEPTH_SIZE, mode.Depth); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_DEPTH_SIZE, mode.Depth);
if (mode.Stencil > 0) if (mode.Stencil > 0)
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_STENCIL_SIZE, mode.Stencil); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_STENCIL_SIZE, mode.Stencil);
if (mode.AccumulatorFormat.BitsPerPixel > 0) if (mode.AccumulatorFormat.BitsPerPixel > 0)
{ {
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_RED_SIZE, mode.AccumulatorFormat.Red); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_ACCUM_RED_SIZE, mode.AccumulatorFormat.Red);
@ -120,72 +118,68 @@ namespace OpenTK.Platform.MacOS
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLE_BUFFERS_ARB, 1); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLE_BUFFERS_ARB, 1);
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLES_ARB, mode.Samples); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_SAMPLES_ARB, mode.Samples);
} }
if (fullscreen) if (fullscreen)
{ {
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_FULLSCREEN); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_FULLSCREEN);
} }
AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_NONE); AddPixelAttrib(aglAttributes, Agl.PixelFormatAttribute.AGL_NONE);
Debug.Unindent(); Debug.Unindent();
Debug.Write("Attribute array: "); Debug.Write("Attribute array: ");
for (int i = 0; i < aglAttributes.Count; i++) for (int i = 0; i < aglAttributes.Count; i++)
Debug.Write(aglAttributes[i].ToString() + " "); Debug.Write(aglAttributes[i].ToString() + " ");
Debug.WriteLine(""); Debug.WriteLine("");
AGLPixelFormat myAGLPixelFormat; AGLPixelFormat myAGLPixelFormat;
// Choose a pixel format with the attributes we specified. // Choose a pixel format with the attributes we specified.
if (fullscreen) if (fullscreen)
{ {
IntPtr gdevice; IntPtr gdevice;
IntPtr cgdevice = GetQuartzDevice(carbonWindow); IntPtr cgdevice = GetQuartzDevice(carbonWindow);
if (cgdevice == IntPtr.Zero) if (cgdevice == IntPtr.Zero)
cgdevice = QuartzDisplayDeviceDriver.MainDisplay; cgdevice = QuartzDisplayDeviceDriver.MainDisplay;
OSStatus status = Carbon.API.DMGetGDeviceByDisplayID( OSStatus status = Carbon.API.DMGetGDeviceByDisplayID(cgdevice, out gdevice, false);
cgdevice, out gdevice, false);
if (status != OSStatus.NoError) if (status != OSStatus.NoError)
throw new MacOSException(status, "DMGetGDeviceByDisplayID failed."); throw new MacOSException(status, "DMGetGDeviceByDisplayID failed.");
myAGLPixelFormat = Agl.aglChoosePixelFormat( myAGLPixelFormat = Agl.aglChoosePixelFormat(ref gdevice, 1, aglAttributes.ToArray());
ref gdevice, 1,
aglAttributes.ToArray());
Agl.AglError err = Agl.GetError(); Agl.AglError err = Agl.GetError();
if (err == Agl.AglError.BadPixelFormat) if (err == Agl.AglError.BadPixelFormat)
{ {
Debug.Print("Failed to create full screen pixel format."); Debug.Print("Failed to create full screen pixel format.");
Debug.Print("Trying again to create a non-fullscreen pixel format."); Debug.Print("Trying again to create a non-fullscreen pixel format.");
CreateContext(mode, carbonWindow, shareContextRef, false); CreateContext(mode, carbonWindow, shareContextRef, false);
return; return;
} }
} }
else else
{ {
myAGLPixelFormat = Agl.aglChoosePixelFormat( myAGLPixelFormat = Agl.aglChoosePixelFormat(IntPtr.Zero, 0, aglAttributes.ToArray());
IntPtr.Zero, 0,
aglAttributes.ToArray());
MyAGLReportError("aglChoosePixelFormat"); MyAGLReportError("aglChoosePixelFormat");
} }
Debug.Print("Creating AGL context. Sharing with {0}", shareContextRef); Debug.Print("Creating AGL context. Sharing with {0}", shareContextRef);
// create the context and share it with the share reference. // create the context and share it with the share reference.
Handle = new ContextHandle( Agl.aglCreateContext(myAGLPixelFormat, shareContextRef)); Handle = new ContextHandle(Agl.aglCreateContext(myAGLPixelFormat, shareContextRef));
MyAGLReportError("aglCreateContext"); MyAGLReportError("aglCreateContext");
// Free the pixel format from memory. // Free the pixel format from memory.
Agl.aglDestroyPixelFormat(myAGLPixelFormat); Agl.aglDestroyPixelFormat(myAGLPixelFormat);
MyAGLReportError("aglDestroyPixelFormat"); MyAGLReportError("aglDestroyPixelFormat");
Debug.Print("IsControl: {0}", carbonWindow.IsControl); Debug.Print("IsControl: {0}", carbonWindow.IsControl);
SetDrawable(carbonWindow); SetDrawable(carbonWindow);
@ -193,29 +187,29 @@ namespace OpenTK.Platform.MacOS
Update(carbonWindow); Update(carbonWindow);
MakeCurrent(carbonWindow); MakeCurrent(carbonWindow);
Debug.Print("context: {0}", Handle.Handle); Debug.Print("context: {0}", Handle.Handle);
} }
private IntPtr GetQuartzDevice(CarbonWindowInfo carbonWindow) private IntPtr GetQuartzDevice(CarbonWindowInfo carbonWindow)
{ {
IntPtr windowRef = carbonWindow.WindowRef; IntPtr windowRef = carbonWindow.WindowRef;
if (CarbonGLNative.WindowRefMap.ContainsKey(windowRef) == false) if (CarbonGLNative.WindowRefMap.ContainsKey(windowRef) == false)
return IntPtr.Zero; return IntPtr.Zero;
WeakReference nativeRef = CarbonGLNative.WindowRefMap[windowRef]; WeakReference nativeRef = CarbonGLNative.WindowRefMap[windowRef];
if (nativeRef.IsAlive == false) if (nativeRef.IsAlive == false)
return IntPtr.Zero; return IntPtr.Zero;
CarbonGLNative window = nativeRef.Target as CarbonGLNative; CarbonGLNative window = nativeRef.Target as CarbonGLNative;
if (window == null) if (window == null)
return IntPtr.Zero; return IntPtr.Zero;
return QuartzDisplayDeviceDriver.HandleTo(window.TargetDisplayDevice); return QuartzDisplayDeviceDriver.HandleTo(window.TargetDisplayDevice);
} }
void SetBufferRect(CarbonWindowInfo carbonWindow) void SetBufferRect(CarbonWindowInfo carbonWindow)
{ {
@ -223,16 +217,15 @@ namespace OpenTK.Platform.MacOS
return; return;
System.Windows.Forms.Control ctrl = Control.FromHandle(carbonWindow.WindowRef); System.Windows.Forms.Control ctrl = Control.FromHandle(carbonWindow.WindowRef);
if (ctrl.TopLevelControl == null) if (ctrl.TopLevelControl == null)
return; return;
Rect rect = API.GetControlBounds(carbonWindow.WindowRef); Rect rect = API.GetControlBounds(carbonWindow.WindowRef);
System.Windows.Forms.Form frm = (System.Windows.Forms.Form) ctrl.TopLevelControl; System.Windows.Forms.Form frm = (System.Windows.Forms.Form)ctrl.TopLevelControl;
System.Drawing.Point loc = System.Drawing.Point loc = frm.PointToClient(ctrl.PointToScreen(System.Drawing.Point.Empty));
frm.PointToClient(ctrl.PointToScreen(System.Drawing.Point.Empty));
rect.X = (short)loc.X; rect.X = (short)loc.X;
rect.Y = (short)loc.Y; rect.Y = (short)loc.Y;
@ -243,28 +236,28 @@ namespace OpenTK.Platform.MacOS
Debug.Print(" AGL Coordinate Rect: {0}", rect); Debug.Print(" AGL Coordinate Rect: {0}", rect);
int[] glrect = new int[4]; int[] glrect = new int[4];
glrect[0] = rect.X; glrect[0] = rect.X;
glrect[1] = rect.Y; glrect[1] = rect.Y;
glrect[2] = rect.Width; glrect[2] = rect.Width;
glrect[3] = rect.Height; glrect[3] = rect.Height;
Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_BUFFER_RECT, glrect); Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_BUFFER_RECT, glrect);
MyAGLReportError("aglSetInteger"); MyAGLReportError("aglSetInteger");
Agl.aglEnable(Handle.Handle, Agl.ParameterNames.AGL_BUFFER_RECT); Agl.aglEnable(Handle.Handle, Agl.ParameterNames.AGL_BUFFER_RECT);
MyAGLReportError("aglEnable"); MyAGLReportError("aglEnable");
} }
void SetDrawable(CarbonWindowInfo carbonWindow) void SetDrawable(CarbonWindowInfo carbonWindow)
{ {
IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow); IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow);
//Debug.Print("Setting drawable for context {0} to window port: {1}", Handle.Handle, windowPort); //Debug.Print("Setting drawable for context {0} to window port: {1}", Handle.Handle, windowPort);
Agl.aglSetDrawable(Handle.Handle, windowPort); Agl.aglSetDrawable(Handle.Handle, windowPort);
MyAGLReportError("aglSetDrawable"); MyAGLReportError("aglSetDrawable");
} }
private static IntPtr GetWindowPortForWindowInfo(CarbonWindowInfo carbonWindow) private static IntPtr GetWindowPortForWindowInfo(CarbonWindowInfo carbonWindow)
@ -276,109 +269,109 @@ namespace OpenTK.Platform.MacOS
windowPort = API.GetWindowPort(controlOwner); windowPort = API.GetWindowPort(controlOwner);
} }
else else
windowPort = API.GetWindowPort(carbonWindow.WindowRef); windowPort = API.GetWindowPort(carbonWindow.WindowRef);
return windowPort; return windowPort;
} }
public override void Update(IWindowInfo window) public override void Update(IWindowInfo window)
{ {
CarbonWindowInfo carbonWindow = (CarbonWindowInfo)window; CarbonWindowInfo carbonWindow = (CarbonWindowInfo)window;
if (carbonWindow.GoFullScreenHack)
{
carbonWindow.GoFullScreenHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null)
wind.SetFullscreen(this);
else
Debug.Print("Could not find window!");
return;
}
if (carbonWindow.GoFullScreenHack) else if (carbonWindow.GoWindowedHack)
{ {
carbonWindow.GoFullScreenHack = false; carbonWindow.GoWindowedHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow); CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null) if (wind != null)
wind.SetFullscreen(this); wind.UnsetFullscreen(this);
else else
Debug.Print("Could not find window!"); Debug.Print("Could not find window!");
return; }
}
else if (carbonWindow.GoWindowedHack) if (mIsFullscreen)
{ return;
carbonWindow.GoWindowedHack = false;
CarbonGLNative wind = GetCarbonWindow(carbonWindow);
if (wind != null)
wind.UnsetFullscreen(this);
else
Debug.Print("Could not find window!");
}
if (mIsFullscreen)
return;
SetDrawable(carbonWindow); SetDrawable(carbonWindow);
SetBufferRect(carbonWindow); SetBufferRect(carbonWindow);
Agl.aglUpdateContext(Handle.Handle); Agl.aglUpdateContext(Handle.Handle);
} }
private CarbonGLNative GetCarbonWindow(CarbonWindowInfo carbonWindow) private CarbonGLNative GetCarbonWindow(CarbonWindowInfo carbonWindow)
{ {
WeakReference r = CarbonGLNative.WindowRefMap[carbonWindow.WindowRef]; WeakReference r = CarbonGLNative.WindowRefMap[carbonWindow.WindowRef];
if (r.IsAlive)
{
return (CarbonGLNative)r.Target;
}
if (r.IsAlive) else
{ return null;
return (CarbonGLNative) r.Target; }
}
else
return null;
}
void MyAGLReportError(string function) void MyAGLReportError(string function)
{ {
Agl.AglError err = Agl.GetError(); Agl.AglError err = Agl.GetError();
if (err != Agl.AglError.NoError) if (err != Agl.AglError.NoError)
throw new MacOSException((OSStatus)err, string.Format( throw new MacOSException((OSStatus)err, string.Format("AGL Error from function {0}: {1} {2}", function, err, Agl.ErrorString(err)));
"AGL Error from function {0}: {1} {2}",
function, err, Agl.ErrorString(err)));
} }
bool firstFullScreen = false; bool firstFullScreen = false;
internal void SetFullScreen(CarbonWindowInfo info, out int width, out int height) internal void SetFullScreen(CarbonWindowInfo info, out int width, out int height)
{ {
CarbonGLNative wind = GetCarbonWindow(info); CarbonGLNative wind = GetCarbonWindow(info);
Debug.Print("Switching to full screen {0}x{1} on context {2}", Debug.Print("Switching to full screen {0}x{1} on context {2}", wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, Handle.Handle);
wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, Handle.Handle);
CG.DisplayCapture(GetQuartzDevice(info));
CG.DisplayCapture(GetQuartzDevice(info)); Agl.aglSetFullScreen(Handle.Handle, wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, 0, 0);
Agl.aglSetFullScreen(Handle.Handle, wind.TargetDisplayDevice.Width, wind.TargetDisplayDevice.Height, 0, 0); MakeCurrent(info);
MakeCurrent(info);
width = wind.TargetDisplayDevice.Width;
width = wind.TargetDisplayDevice.Width; height = wind.TargetDisplayDevice.Height;
height = wind.TargetDisplayDevice.Height;
// This is a weird hack to workaround a bug where the first time a context // This is a weird hack to workaround a bug where the first time a context
// is made fullscreen, we just end up with a blank screen. So we undo it as fullscreen // is made fullscreen, we just end up with a blank screen. So we undo it as fullscreen
// and redo it as fullscreen. // and redo it as fullscreen.
if (firstFullScreen == false) if (firstFullScreen == false)
{ {
firstFullScreen = true; firstFullScreen = true;
UnsetFullScreen(info); UnsetFullScreen(info);
SetFullScreen(info, out width, out height); SetFullScreen(info, out width, out height);
} }
mIsFullscreen = true; mIsFullscreen = true;
} }
internal void UnsetFullScreen(CarbonWindowInfo windowInfo) internal void UnsetFullScreen(CarbonWindowInfo windowInfo)
{ {
Debug.Print("Unsetting AGL fullscreen."); Debug.Print("Unsetting AGL fullscreen.");
Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero); Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero);
Agl.aglUpdateContext(Handle.Handle); Agl.aglUpdateContext(Handle.Handle);
CG.DisplayRelease(GetQuartzDevice(windowInfo)); CG.DisplayRelease(GetQuartzDevice(windowInfo));
Debug.Print("Resetting drawable."); Debug.Print("Resetting drawable.");
SetDrawable(windowInfo); SetDrawable(windowInfo);
mIsFullscreen = false; mIsFullscreen = false;
} }
@ -393,14 +386,14 @@ namespace OpenTK.Platform.MacOS
{ {
Debug.WriteLine("--> Resetting drawable. <--"); Debug.WriteLine("--> Resetting drawable. <--");
firstSwap = true; firstSwap = true;
SetDrawable(carbonWindow); SetDrawable(carbonWindow);
Update(carbonWindow); Update(carbonWindow);
} }
Agl.aglSwapBuffers(Handle.Handle); Agl.aglSwapBuffers(Handle.Handle);
MyAGLReportError("aglSwapBuffers"); MyAGLReportError("aglSwapBuffers");
} }
public override void MakeCurrent(IWindowInfo window) public override void MakeCurrent(IWindowInfo window)
{ {
if (Agl.aglSetCurrentContext(Handle.Handle) == false) if (Agl.aglSetCurrentContext(Handle.Handle) == false)
@ -409,24 +402,18 @@ namespace OpenTK.Platform.MacOS
public override bool IsCurrent public override bool IsCurrent
{ {
get get { return (Handle.Handle == Agl.aglGetCurrentContext()); }
{
return (Handle.Handle == Agl.aglGetCurrentContext());
}
} }
public override bool VSync public override bool VSync
{ {
get get { return mVSync; }
{
return mVSync;
}
set set
{ {
int intVal = value ? 1 : 0; int intVal = value ? 1 : 0;
Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref intVal); Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref intVal);
mVSync = value; mVSync = value;
} }
} }
@ -449,34 +436,34 @@ namespace OpenTK.Platform.MacOS
{ {
if (IsDisposed || Handle.Handle == IntPtr.Zero) if (IsDisposed || Handle.Handle == IntPtr.Zero)
return; return;
Debug.Print("Disposing of AGL context."); Debug.Print("Disposing of AGL context.");
Agl.aglSetCurrentContext(IntPtr.Zero); Agl.aglSetCurrentContext(IntPtr.Zero);
//Debug.Print("Setting drawable to null for context {0}.", Handle.Handle); //Debug.Print("Setting drawable to null for context {0}.", Handle.Handle);
//Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero); //Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero);
// I do not know MacOS allows us to destroy a context from a separate thread, // I do not know MacOS allows us to destroy a context from a separate thread,
// like the finalizer thread. It's untested, but worst case is probably // like the finalizer thread. It's untested, but worst case is probably
// an exception on application exit, which would be logged to the console. // an exception on application exit, which would be logged to the console.
Debug.Print("Destroying context"); Debug.Print("Destroying context");
if (Agl.aglDestroyContext(Handle.Handle) == true) if (Agl.aglDestroyContext(Handle.Handle) == true)
{ {
Debug.Print("Context destruction completed successfully."); Debug.Print("Context destruction completed successfully.");
Handle = ContextHandle.Zero; Handle = ContextHandle.Zero;
return; return;
} }
// failed to destroy context. // failed to destroy context.
Debug.WriteLine("Failed to destroy context."); Debug.WriteLine("Failed to destroy context.");
Debug.WriteLine(Agl.ErrorString(Agl.GetError())); Debug.WriteLine(Agl.ErrorString(Agl.GetError()));
// don't throw an exception from the finalizer thread. // don't throw an exception from the finalizer thread.
if (disposing) if (disposing)
{ {
throw new MacOSException((OSStatus)Agl.GetError(), Agl.ErrorString(Agl.GetError())); throw new MacOSException((OSStatus)Agl.GetError(), Agl.ErrorString(Agl.GetError()));
} }
IsDisposed = true; IsDisposed = true;
} }
@ -484,7 +471,7 @@ namespace OpenTK.Platform.MacOS
#region IGraphicsContextInternal Members #region IGraphicsContextInternal Members
private const string Library = "libdl.dylib"; private const string Library = "libdl.dylib";
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")] [DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
private static extern bool NSIsSymbolNameDefined(string s); private static extern bool NSIsSymbolNameDefined(string s);
@ -498,14 +485,14 @@ namespace OpenTK.Platform.MacOS
string fname = "_" + function; string fname = "_" + function;
if (!NSIsSymbolNameDefined(fname)) if (!NSIsSymbolNameDefined(fname))
return IntPtr.Zero; return IntPtr.Zero;
IntPtr symbol = NSLookupAndBindSymbol(fname); IntPtr symbol = NSLookupAndBindSymbol(fname);
if (symbol != IntPtr.Zero) if (symbol != IntPtr.Zero)
symbol = NSAddressOfSymbol(symbol); symbol = NSAddressOfSymbol(symbol);
return symbol; return symbol;
} }
#endregion #endregion
} }
} }

View file

@ -27,35 +27,36 @@ namespace OpenTK.Platform.MacOS.Carbon
Initialize(); Initialize();
} }
internal static void Initialize() static internal void Initialize()
{ {
if (mInitialized) return; if (mInitialized)
return;
API.AcquireRootMenu(); API.AcquireRootMenu();
ConnectEvents(); ConnectEvents();
API.Gestalt(GestaltSelector.SystemVersionMajor, out osMajor); API.Gestalt(GestaltSelector.SystemVersionMajor, out osMajor);
API.Gestalt(GestaltSelector.SystemVersionMinor, out osMinor); API.Gestalt(GestaltSelector.SystemVersionMinor, out osMinor);
API.Gestalt(GestaltSelector.SystemVersionBugFix, out osBugfix); API.Gestalt(GestaltSelector.SystemVersionBugFix, out osBugfix);
Debug.Print("Running on Mac OS X {0}.{1}.{2}.", osMajor, osMinor, osBugfix); Debug.Print("Running on Mac OS X {0}.{1}.{2}.", osMajor, osMinor, osBugfix);
TransformProcessToForeground(); TransformProcessToForeground();
} }
private static void TransformProcessToForeground() private static void TransformProcessToForeground()
{ {
Carbon.ProcessSerialNumber psn = new ProcessSerialNumber(); Carbon.ProcessSerialNumber psn = new ProcessSerialNumber();
Debug.Print("Setting process to be foreground application.");
API.GetCurrentProcess(ref psn);
API.TransformProcessType(ref psn, ProcessApplicationTransformState.kProcessTransformToForegroundApplication);
API.SetFrontProcess(ref psn);
}
Debug.Print("Setting process to be foreground application."); static internal CarbonGLNative WindowEventHandler
API.GetCurrentProcess(ref psn);
API.TransformProcessType(ref psn, ProcessApplicationTransformState.kProcessTransformToForegroundApplication);
API.SetFrontProcess(ref psn);
}
internal static CarbonGLNative WindowEventHandler
{ {
get { return eventHandler; } get { return eventHandler; }
set { eventHandler = value; } set { eventHandler = value; }
@ -63,33 +64,16 @@ namespace OpenTK.Platform.MacOS.Carbon
static void ConnectEvents() static void ConnectEvents()
{ {
EventTypeSpec[] eventTypes = new EventTypeSpec[]
{ EventTypeSpec[] eventTypes = new EventTypeSpec[] { new EventTypeSpec(EventClass.Application, AppEventKind.AppActivated), new EventTypeSpec(EventClass.Application, AppEventKind.AppDeactivated), new EventTypeSpec(EventClass.Application, AppEventKind.AppQuit), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseMoved), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDragged), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseEntered), new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseExited), new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelMoved),
new EventTypeSpec(EventClass.Application, AppEventKind.AppActivated),
new EventTypeSpec(EventClass.Application, AppEventKind.AppDeactivated),
new EventTypeSpec(EventClass.Application, AppEventKind.AppQuit), new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyDown), new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat), new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp), new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged), new EventTypeSpec(EventClass.AppleEvent, AppleEventKind.AppleEvent) };
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDown),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseUp),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseMoved),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseDragged),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseEntered),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.MouseExited),
new EventTypeSpec(EventClass.Mouse, MouseEventKind.WheelMoved),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyDown),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyRepeat),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyUp),
new EventTypeSpec(EventClass.Keyboard, KeyboardEventKind.RawKeyModifiersChanged),
new EventTypeSpec(EventClass.AppleEvent, AppleEventKind.AppleEvent),
};
MacOSEventHandler handler = EventHandler; MacOSEventHandler handler = EventHandler;
uppHandler = API.NewEventHandlerUPP(handler); uppHandler = API.NewEventHandlerUPP(handler);
API.InstallApplicationEventHandler( API.InstallApplicationEventHandler(uppHandler, eventTypes, IntPtr.Zero, IntPtr.Zero);
uppHandler, eventTypes, IntPtr.Zero, IntPtr.Zero);
mInitialized = true; mInitialized = true;
} }
@ -100,28 +84,30 @@ namespace OpenTK.Platform.MacOS.Carbon
switch (evt.EventClass) switch (evt.EventClass)
{ {
case EventClass.Application: case EventClass.Application:
switch (evt.AppEventKind) switch (evt.AppEventKind)
{ {
default: default:
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
} }
case EventClass.AppleEvent:
// only event here is the apple event. case EventClass.AppleEvent:
Debug.Print("Processing apple event."); // only event here is the apple event.
API.ProcessAppleEvent(inEvent); Debug.Print("Processing apple event.");
break; API.ProcessAppleEvent(inEvent);
break;
case EventClass.Keyboard:
case EventClass.Mouse:
if (WindowEventHandler != null)
{
return WindowEventHandler.DispatchEvent(inCaller, inEvent, evt, userData);
}
case EventClass.Keyboard: break;
case EventClass.Mouse:
if (WindowEventHandler != null)
{
return WindowEventHandler.DispatchEvent(inCaller, inEvent, evt, userData);
}
break;
} }
return OSStatus.EventNotHandled; return OSStatus.EventNotHandled;
} }
@ -129,9 +115,9 @@ namespace OpenTK.Platform.MacOS.Carbon
{ {
window.Closed += MainWindowClosed; window.Closed += MainWindowClosed;
window.Visible = true; window.Visible = true;
API.RunApplicationEventLoop(); API.RunApplicationEventLoop();
window.Closed -= MainWindowClosed; window.Closed -= MainWindowClosed;
} }
@ -142,7 +128,7 @@ namespace OpenTK.Platform.MacOS.Carbon
} }
internal static void ProcessEvents() static internal void ProcessEvents()
{ {
API.ProcessEvents(); API.ProcessEvents();
} }

File diff suppressed because it is too large Load diff

View file

@ -65,17 +65,26 @@ namespace OpenTK.Platform.MacOS
public IMouseDriver2 MouseDriver public IMouseDriver2 MouseDriver
{ {
get { throw new NotImplementedException(); } get
{
throw new NotImplementedException();
}
} }
public IKeyboardDriver2 KeyboardDriver public IKeyboardDriver2 KeyboardDriver
{ {
get { throw new NotImplementedException(); } get
{
throw new NotImplementedException();
}
} }
public IGamePadDriver GamePadDriver public IGamePadDriver GamePadDriver
{ {
get { throw new NotImplementedException(); } get
{
throw new NotImplementedException();
}
} }
} }
} }

View file

@ -36,14 +36,14 @@ namespace OpenTK.Platform.MacOS
/// <summary> /// <summary>
/// Describes a Carbon window. /// Describes a Carbon window.
/// </summary> /// </summary>
sealed class CarbonWindowInfo : IWindowInfo sealed class CarbonWindowInfo : IWindowInfo
{ {
IntPtr windowRef; IntPtr windowRef;
bool ownHandle = false; bool ownHandle = false;
bool disposed = false; bool disposed = false;
bool isControl = false; bool isControl = false;
bool goFullScreenHack = false; bool goFullScreenHack = false;
bool goWindowedHack = false; bool goWindowedHack = false;
#region Constructors #region Constructors
@ -72,16 +72,16 @@ namespace OpenTK.Platform.MacOS
get { return this.windowRef; } get { return this.windowRef; }
} }
internal bool GoFullScreenHack internal bool GoFullScreenHack
{ {
get { return goFullScreenHack; } get { return goFullScreenHack; }
set { goFullScreenHack = value; } set { goFullScreenHack = value; }
} }
internal bool GoWindowedHack internal bool GoWindowedHack
{ {
get { return goWindowedHack; } get { return goWindowedHack; }
set { goWindowedHack = value; } set { goWindowedHack = value; }
} }
/// <summary> /// <summary>
@ -96,8 +96,7 @@ namespace OpenTK.Platform.MacOS
/// <returns>A System.String that represents the current window.</returns> /// <returns>A System.String that represents the current window.</returns>
public override string ToString() public override string ToString()
{ {
return String.Format("MacOS.CarbonWindowInfo: Handle {0}", return String.Format("MacOS.CarbonWindowInfo: Handle {0}", this.WindowRef);
this.WindowRef);
} }
#endregion #endregion
@ -113,19 +112,19 @@ namespace OpenTK.Platform.MacOS
{ {
if (disposed) if (disposed)
return; return;
if (disposing) if (disposing)
{ {
} }
if (ownHandle) if (ownHandle)
{ {
Debug.Print("Disposing window {0}.", windowRef); Debug.Print("Disposing window {0}.", windowRef);
Carbon.API.DisposeWindow(this.windowRef); Carbon.API.DisposeWindow(this.windowRef);
windowRef = IntPtr.Zero; windowRef = IntPtr.Zero;
} }
disposed = true; disposed = true;
} }
@ -133,7 +132,7 @@ namespace OpenTK.Platform.MacOS
{ {
Dispose(false); Dispose(false);
} }
#endregion #endregion
} }
} }

View file

@ -25,14 +25,17 @@ namespace OpenTK.Platform.MacOS.Carbon
uint _eventKind; uint _eventKind;
EventClass _eventClass; EventClass _eventClass;
public EventClass EventClass { get { return _eventClass; }} public EventClass EventClass
{
get { return _eventClass; }
}
public WindowEventKind WindowEventKind public WindowEventKind WindowEventKind
{ {
get get
{ {
if (EventClass == EventClass.Window) if (EventClass == EventClass.Window)
return (WindowEventKind) _eventKind; return (WindowEventKind)_eventKind;
else else
throw new InvalidCastException("Event is not a Window event."); throw new InvalidCastException("Event is not a Window event.");
} }
@ -42,7 +45,7 @@ namespace OpenTK.Platform.MacOS.Carbon
get get
{ {
if (EventClass == EventClass.Keyboard) if (EventClass == EventClass.Keyboard)
return (KeyboardEventKind) _eventKind; return (KeyboardEventKind)_eventKind;
else else
throw new InvalidCastException("Event is not a Keyboard event."); throw new InvalidCastException("Event is not a Keyboard event.");
} }
@ -52,7 +55,7 @@ namespace OpenTK.Platform.MacOS.Carbon
get get
{ {
if (EventClass == EventClass.Mouse) if (EventClass == EventClass.Mouse)
return (MouseEventKind) _eventKind; return (MouseEventKind)_eventKind;
else else
throw new InvalidCastException("Event is not an Mouse event."); throw new InvalidCastException("Event is not an Mouse event.");
} }
@ -62,7 +65,7 @@ namespace OpenTK.Platform.MacOS.Carbon
get get
{ {
if (EventClass == EventClass.Application) if (EventClass == EventClass.Application)
return (AppEventKind) _eventKind; return (AppEventKind)_eventKind;
else else
throw new InvalidCastException("Event is not an Application event."); throw new InvalidCastException("Event is not an Application event.");
} }
@ -71,18 +74,18 @@ namespace OpenTK.Platform.MacOS.Carbon
public override string ToString() public override string ToString()
{ {
switch(EventClass) switch (EventClass)
{ {
case EventClass.Application: case EventClass.Application:
return "Event: App " + AppEventKind.ToString(); return "Event: App " + AppEventKind.ToString();
case EventClass.Keyboard: case EventClass.Keyboard:
return "Event: Keyboard " + KeyboardEventKind.ToString(); return "Event: Keyboard " + KeyboardEventKind.ToString();
case EventClass.Mouse: case EventClass.Mouse:
return "Event: Mouse " + MouseEventKind.ToString(); return "Event: Mouse " + MouseEventKind.ToString();
case EventClass.Window: case EventClass.Window:
return "Event: Window " + WindowEventKind.ToString(); return "Event: Window " + WindowEventKind.ToString();
} }
return "Event: Unknown Class " + EventClass.ToString() + " kind: " + _eventKind.ToString(); return "Event: Unknown Class " + EventClass.ToString() + " kind: " + _eventKind.ToString();
} }
} }

View file

@ -55,7 +55,7 @@ namespace OpenTK.Platform.MacOS
public virtual IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) public virtual IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{ {
return new AglContext(handle, window, shareContext); return new AglContext(handle, window, shareContext);
} }
public virtual GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext() public virtual GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
{ {
@ -79,7 +79,7 @@ namespace OpenTK.Platform.MacOS
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
#endregion #endregion
} }
} }

View file

@ -6,20 +6,19 @@ namespace OpenTK.Platform.MacOS
{ {
using Graphics; using Graphics;
class MacOSGraphicsMode : IGraphicsMode class MacOSGraphicsMode : IGraphicsMode
{ {
#region IGraphicsMode Members #region IGraphicsMode Members
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo) public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
{ {
GraphicsMode gfx = new GraphicsMode((IntPtr)1, color, depth, stencil, samples, GraphicsMode gfx = new GraphicsMode((IntPtr)1, color, depth, stencil, samples, accum, buffers, stereo);
accum, buffers, stereo);
System.Diagnostics.Debug.Print("Created dummy graphics mode."); System.Diagnostics.Debug.Print("Created dummy graphics mode.");
return gfx; return gfx;
} }
#endregion #endregion
} }
} }

View file

@ -12,7 +12,7 @@ namespace OpenTK.Platform.MacOS
public MacOSKeyMap() public MacOSKeyMap()
{ {
// comments indicate members of the Key enum that are missing // comments indicate members of the Key enum that are missing
Add(MacOSKeyCode.A, Key.A); Add(MacOSKeyCode.A, Key.A);
// AltLeft // AltLeft
// AltRight // AltRight
@ -127,7 +127,7 @@ namespace OpenTK.Platform.MacOS
Add(MacOSKeyCode.X, Key.X); Add(MacOSKeyCode.X, Key.X);
Add(MacOSKeyCode.Y, Key.Y); Add(MacOSKeyCode.Y, Key.Y);
Add(MacOSKeyCode.Z, Key.Z); Add(MacOSKeyCode.Z, Key.Z);
} }
} }
} }

View file

@ -11,11 +11,13 @@ namespace OpenTK.Platform.MacOS
{ {
static object display_lock = new object(); static object display_lock = new object();
static Dictionary<DisplayDevice, IntPtr> displayMap = static Dictionary<DisplayDevice, IntPtr> displayMap = new Dictionary<DisplayDevice, IntPtr>();
new Dictionary<DisplayDevice, IntPtr>();
static IntPtr mainDisplay; static IntPtr mainDisplay;
internal static IntPtr MainDisplay { get { return mainDisplay; } } static internal IntPtr MainDisplay
{
get { return mainDisplay; }
}
static QuartzDisplayDeviceDriver() static QuartzDisplayDeviceDriver()
{ {
@ -30,135 +32,130 @@ namespace OpenTK.Platform.MacOS
const int maxDisplayCount = 20; const int maxDisplayCount = 20;
IntPtr[] displays = new IntPtr[maxDisplayCount]; IntPtr[] displays = new IntPtr[maxDisplayCount];
int displayCount; int displayCount;
unsafe unsafe
{ {
fixed(IntPtr* displayPtr = displays) fixed (IntPtr* displayPtr = displays)
{ {
CG.GetActiveDisplayList(maxDisplayCount, displayPtr, out displayCount); CG.GetActiveDisplayList(maxDisplayCount, displayPtr, out displayCount);
} }
} }
Debug.Print("CoreGraphics reported {0} display(s).", displayCount); Debug.Print("CoreGraphics reported {0} display(s).", displayCount);
Debug.Indent(); Debug.Indent();
for (int i = 0; i < displayCount; i++) for (int i = 0; i < displayCount; i++)
{ {
IntPtr currentDisplay = displays[i]; IntPtr currentDisplay = displays[i];
// according to docs, first element in the array is always the // according to docs, first element in the array is always the
// main display. // main display.
bool primary = (i == 0); bool primary = (i == 0);
if (primary) if (primary)
mainDisplay = currentDisplay; mainDisplay = currentDisplay;
// gets current settings // gets current settings
int currentWidth = CG.DisplayPixelsWide(currentDisplay); int currentWidth = CG.DisplayPixelsWide(currentDisplay);
int currentHeight = CG.DisplayPixelsHigh(currentDisplay); int currentHeight = CG.DisplayPixelsHigh(currentDisplay);
Debug.Print("Display {0} is at {1}x{2}", i, currentWidth, currentHeight); Debug.Print("Display {0} is at {1}x{2}", i, currentWidth, currentHeight);
IntPtr displayModesPtr = CG.DisplayAvailableModes(currentDisplay); IntPtr displayModesPtr = CG.DisplayAvailableModes(currentDisplay);
CFArray displayModes = new CFArray(displayModesPtr); CFArray displayModes = new CFArray(displayModesPtr);
Debug.Print("Supports {0} display modes.", displayModes.Count); Debug.Print("Supports {0} display modes.", displayModes.Count);
DisplayResolution opentk_dev_current_res = null; DisplayResolution opentk_dev_current_res = null;
List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>(); List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
IntPtr currentModePtr = CG.DisplayCurrentMode(currentDisplay); IntPtr currentModePtr = CG.DisplayCurrentMode(currentDisplay);
CFDictionary currentMode = new CFDictionary(currentModePtr); CFDictionary currentMode = new CFDictionary(currentModePtr);
for (int j = 0; j < displayModes.Count; j++) for (int j = 0; j < displayModes.Count; j++)
{ {
CFDictionary dict = new CFDictionary(displayModes[j]); CFDictionary dict = new CFDictionary(displayModes[j]);
int width = (int) dict.GetNumberValue("Width"); int width = (int)dict.GetNumberValue("Width");
int height = (int) dict.GetNumberValue("Height"); int height = (int)dict.GetNumberValue("Height");
int bpp = (int) dict.GetNumberValue("BitsPerPixel"); int bpp = (int)dict.GetNumberValue("BitsPerPixel");
double freq = dict.GetNumberValue("RefreshRate"); double freq = dict.GetNumberValue("RefreshRate");
bool current = currentMode.Ref == dict.Ref; bool current = currentMode.Ref == dict.Ref;
//if (current) Debug.Write(" * "); //if (current) Debug.Write(" * ");
//else Debug.Write(" "); //else Debug.Write(" ");
//Debug.Print("Mode {0} is {1}x{2}x{3} @ {4}.", j, width, height, bpp, freq); //Debug.Print("Mode {0} is {1}x{2}x{3} @ {4}.", j, width, height, bpp, freq);
DisplayResolution thisRes = new DisplayResolution(0, 0, width, height, bpp, (float)freq); DisplayResolution thisRes = new DisplayResolution(0, 0, width, height, bpp, (float)freq);
opentk_dev_available_res.Add(thisRes); opentk_dev_available_res.Add(thisRes);
if (current) if (current)
opentk_dev_current_res = thisRes; opentk_dev_current_res = thisRes;
} }
HIRect bounds = CG.DisplayBounds(currentDisplay); HIRect bounds = CG.DisplayBounds(currentDisplay);
Rectangle newRect = new Rectangle( Rectangle newRect = new Rectangle((int)bounds.Origin.X, (int)bounds.Origin.Y, (int)bounds.Size.Width, (int)bounds.Size.Height);
(int)bounds.Origin.X, (int)bounds.Origin.Y, (int)bounds.Size.Width, (int)bounds.Size.Height);
Debug.Print("Display {0} bounds: {1}", i, newRect);
Debug.Print("Display {0} bounds: {1}", i, newRect);
DisplayDevice opentk_dev = new DisplayDevice(opentk_dev_current_res, primary, opentk_dev_available_res, newRect);
DisplayDevice opentk_dev =
new DisplayDevice(opentk_dev_current_res, primary, opentk_dev_available_res, newRect);
displayMap.Add(opentk_dev, currentDisplay); displayMap.Add(opentk_dev, currentDisplay);
} }
Debug.Unindent(); Debug.Unindent();
} }
} }
internal static IntPtr HandleTo(DisplayDevice displayDevice) static internal IntPtr HandleTo(DisplayDevice displayDevice)
{ {
if (displayMap.ContainsKey(displayDevice)) if (displayMap.ContainsKey(displayDevice))
return displayMap[displayDevice]; return displayMap[displayDevice];
else else
return IntPtr.Zero; return IntPtr.Zero;
} }
#region IDisplayDeviceDriver Members #region IDisplayDeviceDriver Members
Dictionary<IntPtr, IntPtr> storedModes = new Dictionary<IntPtr, IntPtr>(); Dictionary<IntPtr, IntPtr> storedModes = new Dictionary<IntPtr, IntPtr>();
List<IntPtr> displaysCaptured = new List<IntPtr>(); List<IntPtr> displaysCaptured = new List<IntPtr>();
public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution) public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
{ {
IntPtr display = displayMap[device]; IntPtr display = displayMap[device];
IntPtr currentModePtr = CG.DisplayCurrentMode(display); IntPtr currentModePtr = CG.DisplayCurrentMode(display);
if (storedModes.ContainsKey(display) == false) if (storedModes.ContainsKey(display) == false)
{ {
storedModes.Add(display, currentModePtr); storedModes.Add(display, currentModePtr);
} }
IntPtr displayModesPtr = CG.DisplayAvailableModes(display); IntPtr displayModesPtr = CG.DisplayAvailableModes(display);
CFArray displayModes = new CFArray(displayModesPtr); CFArray displayModes = new CFArray(displayModesPtr);
for (int j = 0; j < displayModes.Count; j++) for (int j = 0; j < displayModes.Count; j++)
{ {
CFDictionary dict = new CFDictionary(displayModes[j]); CFDictionary dict = new CFDictionary(displayModes[j]);
int width = (int)dict.GetNumberValue("Width"); int width = (int)dict.GetNumberValue("Width");
int height = (int)dict.GetNumberValue("Height"); int height = (int)dict.GetNumberValue("Height");
int bpp = (int)dict.GetNumberValue("BitsPerPixel"); int bpp = (int)dict.GetNumberValue("BitsPerPixel");
double freq = dict.GetNumberValue("RefreshRate"); double freq = dict.GetNumberValue("RefreshRate");
if (width == resolution.Width && if (width == resolution.Width && height == resolution.Height && bpp == resolution.BitsPerPixel && System.Math.Abs(freq - resolution.RefreshRate) < 1e-6)
height == resolution.Height &&
bpp == resolution.BitsPerPixel &&
System.Math.Abs(freq - resolution.RefreshRate) < 1e-6)
{ {
if (displaysCaptured.Contains(display) == false) if (displaysCaptured.Contains(display) == false)
{ {
CG.DisplayCapture(display); CG.DisplayCapture(display);
} }
Debug.Print("Changing resolution to {0}x{1}x{2}@{3}.", width, height, bpp, freq); Debug.Print("Changing resolution to {0}x{1}x{2}@{3}.", width, height, bpp, freq);
CG.DisplaySwitchToMode(display, displayModes[j]); CG.DisplaySwitchToMode(display, displayModes[j]);
return true; return true;
} }
} }
return false; return false;
} }
@ -166,22 +163,22 @@ namespace OpenTK.Platform.MacOS
public bool TryRestoreResolution(DisplayDevice device) public bool TryRestoreResolution(DisplayDevice device)
{ {
IntPtr display = displayMap[device]; IntPtr display = displayMap[device];
if (storedModes.ContainsKey(display)) if (storedModes.ContainsKey(display))
{ {
Debug.Print("Restoring resolution."); Debug.Print("Restoring resolution.");
CG.DisplaySwitchToMode(display, storedModes[display]); CG.DisplaySwitchToMode(display, storedModes[display]);
CG.DisplayRelease(display); CG.DisplayRelease(display);
displaysCaptured.Remove(display); displaysCaptured.Remove(display);
return true; return true;
} }
return false; return false;
} }
#endregion #endregion
} }
} }