From 8b6520114518906de78507941e378f054903a28d Mon Sep 17 00:00:00 2001 From: kanato Date: Tue, 4 Nov 2008 18:35:17 +0000 Subject: [PATCH] Initial commit with Mac OS support. --- Source/OpenTK/Configuration.cs | 12 +- Source/OpenTK/GLControl.cs | 15 +- Source/OpenTK/GameWindow.cs | 21 +- Source/OpenTK/Graphics/DisplayDevice.cs | 13 +- Source/OpenTK/Graphics/GL/GLHelper.cs | 13 +- Source/OpenTK/Graphics/GraphicsContext.cs | 13 +- Source/OpenTK/Graphics/GraphicsMode.cs | 7 +- Source/OpenTK/Graphics/IGraphicsContext.cs | 7 + Source/OpenTK/OpenTK.dll.config | 4 +- Source/OpenTK/Platform/DummyGLContext.cs | 9 + Source/OpenTK/Platform/Factory.cs | 78 ++ Source/OpenTK/Platform/IPlatformFactory.cs | 19 + Source/OpenTK/Platform/MacOS/AglContext.cs | 316 ++++++++ Source/OpenTK/Platform/MacOS/Application.cs | 102 +++ .../Platform/MacOS/CarbonBindings/Agl.cs | 420 ++++++++++ .../MacOS/CarbonBindings/CarbonAPI.cs | 760 ++++++++++++++++++ .../MacOS/CarbonBindings/CoreFoundation.cs | 116 +++ .../MacOS/CarbonBindings/MacOSKeys.cs | 127 +++ .../QuartzDisplayServicesAPI.cs | 48 ++ .../MacOS/CarbonBindings/SpeechChannel.cs | 37 + .../OpenTK/Platform/MacOS/CarbonGLControl.cs | 44 + .../OpenTK/Platform/MacOS/CarbonGLNative.cs | 627 +++++++++++++++ Source/OpenTK/Platform/MacOS/CarbonInput.cs | 55 ++ .../OpenTK/Platform/MacOS/CarbonWindowInfo.cs | 71 ++ Source/OpenTK/Platform/MacOS/EventInfo.cs | 89 ++ .../OpenTK/Platform/MacOS/MacOSException.cs | 92 +++ Source/OpenTK/Platform/MacOS/MacOSFactory.cs | 40 + .../Platform/MacOS/MacOSGraphicsMode.cs | 25 + Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs | 133 +++ .../MacOS/QuartzDisplayDeviceDriver.cs | 110 +++ Source/OpenTK/Platform/OSX/Functions.cs | 29 - Source/OpenTK/Platform/Utilities.cs | 2 +- .../OpenTK/Platform/Windows/WinGLContext.cs | 13 + Source/OpenTK/Platform/X11/X11GLContext.cs | 6 + 34 files changed, 3392 insertions(+), 81 deletions(-) create mode 100644 Source/OpenTK/Platform/Factory.cs create mode 100644 Source/OpenTK/Platform/IPlatformFactory.cs create mode 100644 Source/OpenTK/Platform/MacOS/AglContext.cs create mode 100644 Source/OpenTK/Platform/MacOS/Application.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonBindings/SpeechChannel.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonGLControl.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonGLNative.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonInput.cs create mode 100644 Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs create mode 100644 Source/OpenTK/Platform/MacOS/EventInfo.cs create mode 100644 Source/OpenTK/Platform/MacOS/MacOSException.cs create mode 100644 Source/OpenTK/Platform/MacOS/MacOSFactory.cs create mode 100644 Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs create mode 100644 Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs create mode 100644 Source/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs delete mode 100644 Source/OpenTK/Platform/OSX/Functions.cs diff --git a/Source/OpenTK/Configuration.cs b/Source/OpenTK/Configuration.cs index e28948f5..34d09950 100644 --- a/Source/OpenTK/Configuration.cs +++ b/Source/OpenTK/Configuration.cs @@ -21,7 +21,7 @@ namespace OpenTK /// Contains configuration options for OpenTK. internal static class Configuration { - static bool runningOnWindows, runningOnX11, runningOnOSX, runningOnLinux; + static bool runningOnWindows, runningOnX11, runningOnMacOS, runningOnLinux; #region --- Constructors --- @@ -44,7 +44,7 @@ namespace OpenTK break; case "Darwin": - runningOnOSX = true; + runningOnMacOS = true; break; default: @@ -67,7 +67,7 @@ namespace OpenTK #endregion - #region internal static bool RunningOnX11 + #region internal static bool RunningOnX11 /// Gets a System.Boolean indicating whether OpenTK is running on an X11 platform. internal static bool RunningOnX11 { get { return runningOnX11; } } @@ -81,10 +81,10 @@ namespace OpenTK #endregion - #region internal static bool RunningOnOSX + #region internal static bool RunningOnMacOS - /// Gets a System.Boolean indicating whether OpenTK is running on an OSX platform. - internal static bool RunningOnOSX { get { return runningOnOSX; } } + /// Gets a System.Boolean indicating whether OpenTK is running on a Mac OS platform. + internal static bool RunningOnMacOS { get { return runningOnMacOS; } } #endregion diff --git a/Source/OpenTK/GLControl.cs b/Source/OpenTK/GLControl.cs index 6d50d389..6f85c319 100644 --- a/Source/OpenTK/GLControl.cs +++ b/Source/OpenTK/GLControl.cs @@ -68,18 +68,21 @@ namespace OpenTK // it would be better to decouple selection from context creation, which will allow us // to clean up this hacky code. The best option is to do this along with multisampling // support. - if (Configuration.RunningOnWindows) - implementation = new OpenTK.Platform.Windows.WinGLControl(mode, this); - else if (Configuration.RunningOnX11) - implementation = new OpenTK.Platform.X11.X11GLControl(mode, this); - else if (Configuration.RunningOnOSX) - throw new PlatformNotSupportedException("Refer to http://www.opentk.com for more information."); + implementation = Platform.Factory.CreateGLControl(mode, this); this.CreateControl(); } #endregion + protected override void OnResize(EventArgs e) + { + if (context != null) + context.Update(window_info); + + base.OnResize(e); + } + #region --- Protected Methods --- /// Raises the HandleCreated event. diff --git a/Source/OpenTK/GameWindow.cs b/Source/OpenTK/GameWindow.cs index e1901870..d367a2da 100644 --- a/Source/OpenTK/GameWindow.cs +++ b/Source/OpenTK/GameWindow.cs @@ -153,14 +153,7 @@ namespace OpenTK if (device == null) device = DisplayDevice.Default; - if (Configuration.RunningOnWindows) - glWindow = new OpenTK.Platform.Windows.WinGLNative(); - else if (Configuration.RunningOnX11) - glWindow = new OpenTK.Platform.X11.X11GLNative(); - else - throw new PlatformNotSupportedException( - "Your platform is not supported currently. Please, refer to http://www.opentk.com for more information."); - + glWindow = Platform.Factory.CreateNativeGLWindow(); glWindow.Destroy += glWindow_Destroy; try @@ -230,9 +223,17 @@ namespace OpenTK /// Stops the main loop. void ExitInternal() { - //Debug.Print("Firing GameWindowExitException"); - throw new GameWindowExitException(); + //Debug.Print("Firing GameWindowExitException"); + if (HasMainLoop) + { + throw new GameWindowExitException(); + } + if (CloseWindow != null) + { + CloseWindow(this, EventArgs.Empty); + } } + public event EventHandler CloseWindow; void CallExitInternal(GameWindow sender, UpdateFrameEventArgs e) { diff --git a/Source/OpenTK/Graphics/DisplayDevice.cs b/Source/OpenTK/Graphics/DisplayDevice.cs index ef529bcc..9c6757b7 100644 --- a/Source/OpenTK/Graphics/DisplayDevice.cs +++ b/Source/OpenTK/Graphics/DisplayDevice.cs @@ -42,17 +42,8 @@ namespace OpenTK.Graphics static DisplayDevice() { - switch (System.Environment.OSVersion.Platform) - { - case PlatformID.Unix: - case (PlatformID)128: - implementation = new OpenTK.Platform.X11.X11XrandrDisplayDevice(); - break; - - default: - implementation = new OpenTK.Platform.Windows.WinDisplayDeviceDriver(); - break; - } + implementation = Platform.Factory.CreateDisplayDeviceDriver(); + //lock (display_lock) //{ // int i = 0; diff --git a/Source/OpenTK/Graphics/GL/GLHelper.cs b/Source/OpenTK/Graphics/GL/GLHelper.cs index 4d17a391..71327457 100644 --- a/Source/OpenTK/Graphics/GL/GLHelper.cs +++ b/Source/OpenTK/Graphics/GL/GLHelper.cs @@ -553,21 +553,22 @@ namespace OpenTK.Graphics { if (getProcAddress == null) { - if (System.Environment.OSVersion.Platform == PlatformID.Win32NT || - System.Environment.OSVersion.Platform == PlatformID.Win32S || - System.Environment.OSVersion.Platform == PlatformID.Win32Windows || - System.Environment.OSVersion.Platform == PlatformID.WinCE) + if (Configuration.RunningOnWindows) { getProcAddress = new GetProcAddressWindows(); } - else if (System.Environment.OSVersion.Platform == PlatformID.Unix) + else if (Configuration.RunningOnMacOS) + { + getProcAddress = new GetProcAddressOSX(); + } + else if (Configuration.RunningOnX11) { getProcAddress = new GetProcAddressX11(); } else { throw new PlatformNotSupportedException( - "Extension loading is only supported under X11 and Windows. We are sorry for the inconvience."); + "Extension loading is only supported under Mac OS X, X11 and Windows. We are sorry for the inconvience."); } } diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs index 1c14b343..f498b546 100644 --- a/Source/OpenTK/Graphics/GraphicsContext.cs +++ b/Source/OpenTK/Graphics/GraphicsContext.cs @@ -72,12 +72,8 @@ namespace OpenTK.Graphics if (designMode) implementation = new OpenTK.Platform.DummyGLContext(mode); - else if (Configuration.RunningOnWindows) - implementation = new OpenTK.Platform.Windows.WinGLContext(mode, window, shareContext); - else if (Configuration.RunningOnX11) - implementation = new OpenTK.Platform.X11.X11GLContext(mode, window, shareContext, DirectRendering); else - throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information."); + implementation = Factory.CreateGLContext(mode, window, shareContext, DirectRendering); lock (context_lock) { @@ -299,6 +295,13 @@ namespace OpenTK.Graphics set { implementation.VSync = value; } } + #region public void Update + public void Update(IWindowInfo window) + { + implementation.Update(window); + } + #endregion + #endregion #region --- IGLContextInternal Members --- diff --git a/Source/OpenTK/Graphics/GraphicsMode.cs b/Source/OpenTK/Graphics/GraphicsMode.cs index 72c87882..26f10cfb 100644 --- a/Source/OpenTK/Graphics/GraphicsMode.cs +++ b/Source/OpenTK/Graphics/GraphicsMode.cs @@ -31,12 +31,7 @@ namespace OpenTK.Graphics static GraphicsMode() { - if (Configuration.RunningOnWindows) - implementation = new OpenTK.Platform.Windows.WinGraphicsMode(); - else if (Configuration.RunningOnX11) - implementation = new OpenTK.Platform.X11.X11GraphicsMode(); - else - throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information."); + implementation = Platform.Factory.CreateGraphicsMode(); } #endregion diff --git a/Source/OpenTK/Graphics/IGraphicsContext.cs b/Source/OpenTK/Graphics/IGraphicsContext.cs index a91d1071..59e024bc 100644 --- a/Source/OpenTK/Graphics/IGraphicsContext.cs +++ b/Source/OpenTK/Graphics/IGraphicsContext.cs @@ -44,6 +44,13 @@ namespace OpenTK.Graphics /// Gets or sets a value indicating whether VSyncing is enabled. /// bool VSync { get; set; } + + /// + /// Updates the graphics context. This must be called when the region the graphics context + /// is drawn to is resized. + /// + /// + void Update(IWindowInfo window); } public delegate void DestroyEvent(T sender, EventArgs e); diff --git a/Source/OpenTK/OpenTK.dll.config b/Source/OpenTK/OpenTK.dll.config index 1c21f56e..d6c9431a 100644 --- a/Source/OpenTK/OpenTK.dll.config +++ b/Source/OpenTK/OpenTK.dll.config @@ -3,4 +3,6 @@ - \ No newline at end of file + + + diff --git a/Source/OpenTK/Platform/DummyGLContext.cs b/Source/OpenTK/Platform/DummyGLContext.cs index 7edadadb..083dea8f 100644 --- a/Source/OpenTK/Platform/DummyGLContext.cs +++ b/Source/OpenTK/Platform/DummyGLContext.cs @@ -87,5 +87,14 @@ namespace OpenTK.Platform } #endregion + + #region IGraphicsContext Members + + + public void Update(IWindowInfo window) + { + } + + #endregion } } diff --git a/Source/OpenTK/Platform/Factory.cs b/Source/OpenTK/Platform/Factory.cs new file mode 100644 index 00000000..a65b739d --- /dev/null +++ b/Source/OpenTK/Platform/Factory.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenTK.Platform +{ + using Graphics; + + static class Factory + { + static IPlatformFactory implementation; + + static Factory() + { + if (Configuration.RunningOnWindows) implementation = new Windows.WinFactory(); + else if (Configuration.RunningOnX11) implementation = new X11.X11Factory(); + else if (Configuration.RunningOnMacOS) implementation = new MacOS.MacOSFactory(); + else implementation = new UnsupportedPlatform(); + } + + internal static INativeGLWindow CreateNativeGLWindow() + { + return implementation.CreateGLNative(); + } + + internal static IGLControl CreateGLControl(GraphicsMode mode, GLControl owner) + { + return implementation.CreateGLControl(mode, owner); + } + + internal static IDisplayDeviceDriver CreateDisplayDeviceDriver() + { + return implementation.CreateDisplayDeviceDriver(); + } + + internal static IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering) + { + return implementation.CreateGLContext(mode, window, shareContext, directRendering); + } + + internal static IGraphicsMode CreateGraphicsMode() + { + return implementation.CreateGraphicsMode(); + } + + class UnsupportedPlatform : IPlatformFactory + { + #region IPlatformFactory Members + + public INativeGLWindow CreateGLNative() + { + throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information."); + } + + public IGLControl CreateGLControl(GraphicsMode mode, GLControl owner) + { + throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information."); + } + + public IDisplayDeviceDriver CreateDisplayDeviceDriver() + { + throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information."); + } + + public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool DirectRendering) + { + throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information."); + } + + public IGraphicsMode CreateGraphicsMode() + { + throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information."); + } + + #endregion + } + } +} diff --git a/Source/OpenTK/Platform/IPlatformFactory.cs b/Source/OpenTK/Platform/IPlatformFactory.cs new file mode 100644 index 00000000..2b3fff7f --- /dev/null +++ b/Source/OpenTK/Platform/IPlatformFactory.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenTK.Platform +{ + interface IPlatformFactory + { + INativeGLWindow CreateGLNative(); + + IGLControl CreateGLControl(OpenTK.Graphics.GraphicsMode mode, GLControl owner); + + OpenTK.Graphics.IDisplayDeviceDriver CreateDisplayDeviceDriver(); + + OpenTK.Graphics.IGraphicsContext CreateGLContext(OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, OpenTK.Graphics.IGraphicsContext shareContext, bool DirectRendering); + + OpenTK.Graphics.IGraphicsMode CreateGraphicsMode(); + } +} diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs new file mode 100644 index 00000000..f621aaa7 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/AglContext.cs @@ -0,0 +1,316 @@ +// +// +// AglContext.cs +// +// Created by Erik Ylvisaker on 3/17/08. +// Copyright 2008. All rights reserved. +// +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace OpenTK.Platform.MacOS +{ + using Carbon; + using Graphics; + using Graphics.OpenGL; + + using AGLRendererInfo = IntPtr; + using AGLPixelFormat = IntPtr; + using AGLContext = IntPtr; + using AGLPbuffer = IntPtr; + + class AglContext : IGraphicsContext, IGraphicsContextInternal + { + IntPtr contextRef; + bool mVSync = false; + IntPtr displayID; + + static AglContext() + { + if (GraphicsContext.GetCurrentContext == null) + GraphicsContext.GetCurrentContext = AglContext.GetCurrentContext; + } + public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext) + { + int[] attributes = + { + (int)Agl.PixelFormatAttribute.AGL_RGBA, + (int)Agl.PixelFormatAttribute.AGL_DOUBLEBUFFER, + (int)Agl.PixelFormatAttribute.AGL_RED_SIZE, mode.ColorFormat.Red, + (int)Agl.PixelFormatAttribute.AGL_GREEN_SIZE, mode.ColorFormat.Green, + (int)Agl.PixelFormatAttribute.AGL_BLUE_SIZE, mode.ColorFormat.Blue, + (int)Agl.PixelFormatAttribute.AGL_ALPHA_SIZE, mode.ColorFormat.Alpha, + (int)Agl.PixelFormatAttribute.AGL_DEPTH_SIZE, mode.Depth, + (int)Agl.PixelFormatAttribute.AGL_STENCIL_SIZE, mode.Stencil, + (int)Agl.PixelFormatAttribute.AGL_ACCUM_RED_SIZE, mode.AccumulatorFormat.Red, + (int)Agl.PixelFormatAttribute.AGL_ACCUM_GREEN_SIZE, mode.AccumulatorFormat.Green, + (int)Agl.PixelFormatAttribute.AGL_ACCUM_BLUE_SIZE, mode.AccumulatorFormat.Blue, + (int)Agl.PixelFormatAttribute.AGL_ACCUM_ALPHA_SIZE, mode.AccumulatorFormat.Alpha, + (int)Agl.PixelFormatAttribute.AGL_FULLSCREEN, + (int)Agl.PixelFormatAttribute.AGL_NONE, + }; + + AGLContext myAGLContext = IntPtr.Zero; + AGLPixelFormat myAGLPixelFormat; + IntPtr shareContextRef = IntPtr.Zero; + CarbonWindowInfo carbonWindow = (CarbonWindowInfo)window; + + // Choose a pixel format with the attributes we specified. + myAGLPixelFormat = Agl.aglChoosePixelFormat(IntPtr.Zero, 0, attributes); + MyAGLReportError(); + + if (shareContext != null) + { + Debug.Print("shareContext type is {0}", shareContext.GetType()); + } + + if (shareContext != null && shareContext is AglContext) + shareContextRef = ((AglContext)shareContext).contextRef; + + // create the context and share it with the share reference. + myAGLContext = Agl.aglCreateContext(myAGLPixelFormat, shareContextRef); + MyAGLReportError(); + + // Free the pixel format from memory. + Agl.aglDestroyPixelFormat(myAGLPixelFormat); + MyAGLReportError(); + + + IntPtr windowPort; + + Debug.Print("IsControl: {0}", carbonWindow.IsControl); + if (carbonWindow.IsControl) + { + IntPtr controlOwner = API.GetControlOwner(carbonWindow.WindowRef); + + Debug.Print("GetControlOwner: {0}", controlOwner); + + windowPort = API.GetWindowPort(controlOwner); + } + else + windowPort = API.GetWindowPort(carbonWindow.WindowRef); + + windowPort = API.GetWindowPort(carbonWindow.WindowRef); + Agl.aglSetDrawable(myAGLContext, windowPort); + + MyAGLReportError(); + + if (carbonWindow.IsControl) + { + Rect rect = API.GetControlBounds(carbonWindow.WindowRef); + HIRect hirect = API.HIViewGetFrame(carbonWindow.WindowRef); + + Debug.Print("Setting buffer_rect for control."); + Debug.Print("Rect: {0}", rect); + Debug.Print("HIRect: {0}", hirect); + + int[] glrect = new int[4]; + + glrect[0] = rect.Left; + glrect[1] = rect.Top; + glrect[2] = rect.Width; + glrect[3] = rect.Height; + + Agl.aglSetInteger(myAGLContext, Agl.ParameterNames.AGL_BUFFER_RECT, glrect); + MyAGLReportError(); + + Agl.aglEnable(myAGLContext, Agl.ParameterNames.AGL_BUFFER_RECT); + MyAGLReportError(); + } + + // + MyAGLReportError(); + + MakeCurrent(window); + + this.contextRef = myAGLContext; + + Debug.Print("context: {0}", contextRef); + } + + public void Update(IWindowInfo window) + { + CarbonWindowInfo carbonWindow = (CarbonWindowInfo)window; + + if (carbonWindow.IsControl) + { + Rect rect = API.GetControlBounds(carbonWindow.WindowRef); + HIRect hirect = API.HIViewGetFrame(carbonWindow.WindowRef); + + Debug.Print("Setting buffer_rect for control."); + Debug.Print("Rect: {0}", rect); + Debug.Print("HIRect: {0}", hirect); + + int[] glrect = new int[4]; + + glrect[0] = rect.Left; + glrect[1] = rect.Top; + glrect[2] = rect.Width; + glrect[3] = rect.Height; + + Agl.aglSetInteger(contextRef, Agl.ParameterNames.AGL_BUFFER_RECT, glrect); + MyAGLReportError(); + + } + //Agl.aglSetCurrentContext(contextRef); + Agl.aglUpdateContext(contextRef); + //Agl.aglSetDrawable(contextRef, API.GetWindowPort(carbonWindow.WindowRef)); + + } + void MyAGLReportError() + { + Agl.AglError err = Agl.GetError(); + + if (err != Agl.AglError.NoError) + throw new MacOSException((OSStatus)err, "AGL Error: " + err.ToString() + " " + Agl.ErrorString(err)); + } + + static ContextHandle GetCurrentContext() + { + return Agl.aglGetCurrentContext(); + } + + #region IGraphicsContext Members + + public void SwapBuffers() + { + Agl.aglSwapBuffers(contextRef); + MyAGLReportError(); + } + + public void MakeCurrent(IWindowInfo window) + { + if (Agl.aglSetCurrentContext(contextRef) == false) + MyAGLReportError(); + } + + public bool IsCurrent + { + get + { + return (contextRef == Agl.aglGetCurrentContext()); + } + } + + public event DestroyEvent Destroy; + void OnDestroy() + { + + if (Destroy != null) + { + Debug.Print("Destroy handlers: {0}", Destroy.GetInvocationList().Length); + Destroy(this, EventArgs.Empty); + } + } + + public bool VSync + { + get + { + return mVSync; + } + set + { + int intVal = value ? 1 : 0; + + Agl.aglSetInteger(this.contextRef, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref intVal); + + mVSync = value; + } + } + + #endregion + + #region IDisposable Members + ~AglContext() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + } + + void Dispose(bool disposing) + { + + if (contextRef == IntPtr.Zero) + return; + + OnDestroy(); + Debug.Print("Disposing of AGL context."); + + try + { + throw new Exception(); + } + catch (Exception e) + { + Debug.WriteLine(e.StackTrace); + } + + Agl.aglSetCurrentContext(IntPtr.Zero); + Agl.aglSetDrawable(contextRef, IntPtr.Zero); + + Debug.Print("Set drawable to null for context {0}.", contextRef); + + if (Agl.aglDestroyContext(contextRef) == true) + { + contextRef = IntPtr.Zero; + return; + } + + // failed to destroy context. + Debug.WriteLine("Failed to destroy context."); + Debug.WriteLine(Agl.ErrorString(Agl.GetError())); + + // don't throw an exception from the finalizer thread. + if (disposing) + { + throw new MacOSException((OSStatus)Agl.GetError(), Agl.ErrorString(Agl.GetError())); + } + } + + #endregion + + #region IGraphicsContextInternal Members + + void IGraphicsContextInternal.LoadAll() + { + GL.LoadAll(); + Glu.LoadAll(); + } + + ContextHandle IGraphicsContextInternal.Context + { + get { return contextRef; } + } + + GraphicsMode IGraphicsContextInternal.GraphicsMode + { + get { throw new Exception("The method or operation is not implemented."); } + } + + void IGraphicsContextInternal.RegisterForDisposal(IDisposable resource) + { + throw new Exception("The method or operation is not implemented."); + } + + void IGraphicsContextInternal.DisposeResources() + { + throw new Exception("The method or operation is not implemented."); + } + + IntPtr IGraphicsContextInternal.GetAddress(string function) + { + throw new Exception("The method or operation is not implemented."); + } + + #endregion + + } +} diff --git a/Source/OpenTK/Platform/MacOS/Application.cs b/Source/OpenTK/Platform/MacOS/Application.cs new file mode 100644 index 00000000..c33e8f0e --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/Application.cs @@ -0,0 +1,102 @@ +// +// +// xCSCarbon +// +// Created by Erik Ylvisaker on 3/17/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// +// + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; + +namespace OpenTK.Platform.MacOS.Carbon +{ + + static class Application + { + static bool mInitialized = false; + static IntPtr uppHandler; + + static Application() + { + Initialize(); + } + + internal static void Initialize() + { + if (mInitialized) return; + + API.AcquireRootMenu(); + + ConnectEvents(); + } + + static void ConnectEvents() + { + 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.AppleEvent, AppleEventKind.AppleEvent), + }; + + MacOSEventHandler handler = EventHandler; + uppHandler = API.NewEventHandlerUPP(handler); + + API.InstallApplicationEventHandler( + uppHandler, eventTypes, IntPtr.Zero, IntPtr.Zero); + + mInitialized = true; + } + + static OSStatus EventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData) + { + EventInfo evt = new EventInfo(inEvent); + + Debug.Print("{0}", evt); + + if (evt.EventClass == EventClass.Application) + { + switch (evt.AppEventKind) + { + default: + return OSStatus.EventNotHandled; + } + } + else if (evt.EventClass == EventClass.AppleEvent) + { + // only event here is the apple event. + API.ProcessAppleEvent(inEvent); + } + + return OSStatus.EventNotHandled; + } + + public static void Run(CarbonGLNative window) + { + window.Destroy += MainWindowClosed; + window.Show(); + + API.RunApplicationEventLoop(); + + window.Destroy -= MainWindowClosed; + } + + static void MainWindowClosed(object sender, EventArgs e) + { + API.QuitApplicationEventLoop(); + } + + + internal static void ProcessEvents() + { + API.ProcessEvents(); + } + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs new file mode 100644 index 00000000..a0eef103 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs @@ -0,0 +1,420 @@ +// +// +// Agl.cs +// +// Created by Erik Ylvisaker on 3/17/08. +// Copyright 2008. All rights reserved. +// +// + +using System; +using System.Runtime.InteropServices; + +namespace OpenTK.Platform.MacOS +{ + /* + ** Macintosh device type. + */ + using AGLDevice = IntPtr; + + /* + ** Macintosh drawable type. + */ + using AGLDrawable = IntPtr; + + /* + ** AGL opaque data. + */ + using AGLRendererInfo = IntPtr; + using AGLPixelFormat = IntPtr; + using AGLContext = IntPtr; + using AGLPbuffer = IntPtr; + + using GLenum = UInt32; + + unsafe static partial class Agl + { + + const string agl = "/System/Library/Frameworks/AGL.framework/Versions/Current/AGL"; + + /* + ** AGL API version. + */ + const int AGL_VERSION_2_0 = 1; + + /************************************************************************/ + + /* + ** Attribute names for aglChoosePixelFormat and aglDescribePixelFormat. + */ + internal enum PixelFormatAttribute + { + AGL_NONE = 0, + AGL_ALL_RENDERERS = 1, /* choose from all available renderers */ + AGL_BUFFER_SIZE = 2, /* depth of the index buffer */ + AGL_LEVEL = 3, /* level in plane stacking */ + AGL_RGBA = 4, /* choose an RGBA format */ + AGL_DOUBLEBUFFER = 5, /* double buffering supported */ + AGL_STEREO = 6, /* stereo buffering supported */ + AGL_AUX_BUFFERS = 7, /* number of aux buffers */ + AGL_RED_SIZE = 8, /* number of red component bits */ + AGL_GREEN_SIZE = 9, /* number of green component bits */ + AGL_BLUE_SIZE = 10, /* number of blue component bits */ + AGL_ALPHA_SIZE = 11, /* number of alpha component bits */ + AGL_DEPTH_SIZE = 12, /* number of depth bits */ + AGL_STENCIL_SIZE = 13, /* number of stencil bits */ + AGL_ACCUM_RED_SIZE = 14, /* number of red accum bits */ + AGL_ACCUM_GREEN_SIZE = 15, /* number of green accum bits */ + AGL_ACCUM_BLUE_SIZE = 16, /* number of blue accum bits */ + AGL_ACCUM_ALPHA_SIZE = 17, /* number of alpha accum bits */ + AGL_PIXEL_SIZE = 50, + AGL_MINIMUM_POLICY = 51, + AGL_MAXIMUM_POLICY = 52, + AGL_OFFSCREEN = 53, + AGL_FULLSCREEN = 54, + AGL_SAMPLE_BUFFERS_ARB = 55, + AGL_SAMPLES_ARB = 56, + AGL_AUX_DEPTH_STENCIL = 57, + AGL_COLOR_FLOAT = 58, + AGL_MULTISAMPLE = 59, + AGL_SUPERSAMPLE = 60, + AGL_SAMPLE_ALPHA = 61, + } + /* + ** Extended attributes + */ + internal enum ExtendedAttribute + { + AGL_PIXEL_SIZE = 50, /* frame buffer bits per pixel */ + AGL_MINIMUM_POLICY = 51, /* never choose smaller buffers than requested */ + AGL_MAXIMUM_POLICY = 52, /* choose largest buffers of type requested */ + AGL_OFFSCREEN = 53, /* choose an off-screen capable renderer */ + AGL_FULLSCREEN = 54, /* choose a full-screen capable renderer */ + AGL_SAMPLE_BUFFERS_ARB = 55, /* number of multi sample buffers */ + AGL_SAMPLES_ARB = 56, /* number of samples per multi sample buffer */ + AGL_AUX_DEPTH_STENCIL = 57, /* independent depth and/or stencil buffers for the aux buffer */ + AGL_COLOR_FLOAT = 58, /* color buffers store floating point pixels */ + AGL_MULTISAMPLE = 59, /* choose multisample */ + AGL_SUPERSAMPLE = 60, /* choose supersample */ + AGL_SAMPLE_ALPHA = 61, /* request alpha filtering */ + } + /* + ** Renderer management + */ + internal enum RendererManagement + { + AGL_RENDERER_ID = 70, /* request renderer by ID */ + AGL_SINGLE_RENDERER = 71, /* choose a single renderer for all screens */ + AGL_NO_RECOVERY = 72, /* disable all failure recovery systems */ + AGL_ACCELERATED = 73, /* choose a hardware accelerated renderer */ + AGL_CLOSEST_POLICY = 74, /* choose the closest color buffer to request */ + AGL_ROBUST = 75, /* renderer does not need failure recovery */ + AGL_BACKING_STORE = 76, /* back buffer contents are valid after swap */ + AGL_MP_SAFE = 78, /* renderer is multi-processor safe */ + + AGL_WINDOW = 80, /* can be used to render to a window */ + AGL_MULTISCREEN = 81, /* single window can span multiple screens */ + AGL_VIRTUAL_SCREEN = 82, /* virtual screen number */ + AGL_COMPLIANT = 83, /* renderer is opengl compliant */ + + AGL_PBUFFER = 90, /* can be used to render to a pbuffer */ + AGL_REMOTE_PBUFFER = 91, /* can be used to render offline to a pbuffer */ + } + /* + ** Property names for aglDescribeRenderer + */ + internal enum RendererProperties + { + /* const int AGL_OFFSCREEN = 53 */ + /* const int AGL_FULLSCREEN = 54 */ + /* const int AGL_RENDERER_ID = 70 */ + /* const int AGL_ACCELERATED = 73 */ + /* const int AGL_ROBUST = 75 */ + /* const int AGL_BACKING_STORE = 76 */ + /* const int AGL_MP_SAFE = 78 */ + /* const int AGL_WINDOW = 80 */ + /* const int AGL_MULTISCREEN = 81 */ + /* const int AGL_COMPLIANT = 83 */ + /* const int AGL_PBUFFER = 90 */ + AGL_BUFFER_MODES = 100, + AGL_MIN_LEVEL = 101, + AGL_MAX_LEVEL = 102, + AGL_COLOR_MODES = 103, + AGL_ACCUM_MODES = 104, + AGL_DEPTH_MODES = 105, + AGL_STENCIL_MODES = 106, + AGL_MAX_AUX_BUFFERS = 107, + AGL_VIDEO_MEMORY = 120, + AGL_TEXTURE_MEMORY = 121, + AGL_RENDERER_COUNT = 128, + } + /* + ** Integer parameter names + */ + internal enum ParameterNames + { + AGL_SWAP_RECT = 200, /* Enable or set the swap rectangle */ + AGL_BUFFER_RECT = 202, /* Enable or set the buffer rectangle */ + AGL_SWAP_LIMIT = 203, /* Enable or disable the swap async limit */ + AGL_COLORMAP_TRACKING = 210, /* Enable or disable colormap tracking */ + AGL_COLORMAP_ENTRY = 212, /* Set a colormap entry to {index, r, g, b} */ + AGL_RASTERIZATION = 220, /* Enable or disable all rasterization */ + AGL_SWAP_INTERVAL = 222, /* 0 -> Don't sync, n -> Sync every n retrace */ + AGL_STATE_VALIDATION = 230, /* Validate state for multi-screen functionality */ + AGL_BUFFER_NAME = 231, /* Set the buffer name. Allows for multi ctx to share a buffer */ + AGL_ORDER_CONTEXT_TO_FRONT = 232, /* Order the current context in front of all the other contexts. */ + AGL_CONTEXT_SURFACE_ID = 233, /* aglGetInteger only - returns the ID of the drawable surface for the context */ + AGL_CONTEXT_DISPLAY_ID = 234, /* aglGetInteger only - returns the display ID(s) of all displays touched by the context, up to a maximum of 32 displays */ + AGL_SURFACE_ORDER = 235, /* Position of OpenGL surface relative to window: 1 -> Above window, -1 -> Below Window */ + AGL_SURFACE_OPACITY = 236, /* Opacity of OpenGL surface: 1 -> Surface is opaque (default), 0 -> non-opaque */ + AGL_CLIP_REGION = 254, /* Enable or set the drawable clipping region */ + AGL_FS_CAPTURE_SINGLE = 255, /* Enable the capture of only a single display for aglFullScreen, normally disabled */ + AGL_SURFACE_BACKING_SIZE = 304, /* 2 params. Width/height of surface backing size */ + AGL_ENABLE_SURFACE_BACKING_SIZE = 305, /* Enable or disable surface backing size override */ + AGL_SURFACE_VOLATILE = 306, /* Flag surface to candidate for deletion */ + } + /* + ** Option names for aglConfigure. + */ + internal enum OptionName + { + AGL_FORMAT_CACHE_SIZE = 501, /* Set the size of the pixel format cache */ + AGL_CLEAR_FORMAT_CACHE = 502, /* Reset the pixel format cache */ + AGL_RETAIN_RENDERERS = 503, /* Whether to retain loaded renderers in memory */ + } + /* buffer_modes */ + internal enum BufferModes + { + AGL_MONOSCOPIC_BIT = 0x00000001, + AGL_STEREOSCOPIC_BIT = 0x00000002, + AGL_SINGLEBUFFER_BIT = 0x00000004, + AGL_DOUBLEBUFFER_BIT = 0x00000008, + } + + internal enum BitDepths + { + /* bit depths */ + AGL_0_BIT = 0x00000001, + AGL_1_BIT = 0x00000002, + AGL_2_BIT = 0x00000004, + AGL_3_BIT = 0x00000008, + AGL_4_BIT = 0x00000010, + AGL_5_BIT = 0x00000020, + AGL_6_BIT = 0x00000040, + AGL_8_BIT = 0x00000080, + AGL_10_BIT = 0x00000100, + AGL_12_BIT = 0x00000200, + AGL_16_BIT = 0x00000400, + AGL_24_BIT = 0x00000800, + AGL_32_BIT = 0x00001000, + AGL_48_BIT = 0x00002000, + AGL_64_BIT = 0x00004000, + AGL_96_BIT = 0x00008000, + AGL_128_BIT = 0x00010000, + } + /* color modes */ + internal enum ColorModes + { + AGL_RGB8_BIT = 0x00000001, /* 8 rgb bit/pixel, RGB=7:0, inverse colormap */ + AGL_RGB8_A8_BIT = 0x00000002, /* 8-8 argb bit/pixel, A=7:0, RGB=7:0, inverse colormap */ + AGL_BGR233_BIT = 0x00000004, /* 8 rgb bit/pixel, B=7:6, G=5:3, R=2:0 */ + AGL_BGR233_A8_BIT = 0x00000008, /* 8-8 argb bit/pixel, A=7:0, B=7:6, G=5:3, R=2:0 */ + AGL_RGB332_BIT = 0x00000010, /* 8 rgb bit/pixel, R=7:5, G=4:2, B=1:0 */ + AGL_RGB332_A8_BIT = 0x00000020, /* 8-8 argb bit/pixel, A=7:0, R=7:5, G=4:2, B=1:0 */ + AGL_RGB444_BIT = 0x00000040, /* 16 rgb bit/pixel, R=11:8, G=7:4, B=3:0 */ + AGL_ARGB4444_BIT = 0x00000080, /* 16 argb bit/pixel, A=15:12, R=11:8, G=7:4, B=3:0 */ + AGL_RGB444_A8_BIT = 0x00000100, /* 8-16 argb bit/pixel, A=7:0, R=11:8, G=7:4, B=3:0 */ + AGL_RGB555_BIT = 0x00000200, /* 16 rgb bit/pixel, R=14:10, G=9:5, B=4:0 */ + AGL_ARGB1555_BIT = 0x00000400, /* 16 argb bit/pixel, A=15, R=14:10, G=9:5, B=4:0 */ + AGL_RGB555_A8_BIT = 0x00000800, /* 8-16 argb bit/pixel, A=7:0, R=14:10, G=9:5, B=4:0 */ + AGL_RGB565_BIT = 0x00001000, /* 16 rgb bit/pixel, R=15:11, G=10:5, B=4:0 */ + AGL_RGB565_A8_BIT = 0x00002000, /* 8-16 argb bit/pixel, A=7:0, R=15:11, G=10:5, B=4:0 */ + AGL_RGB888_BIT = 0x00004000, /* 32 rgb bit/pixel, R=23:16, G=15:8, B=7:0 */ + AGL_ARGB8888_BIT = 0x00008000, /* 32 argb bit/pixel, A=31:24, R=23:16, G=15:8, B=7:0 */ + AGL_RGB888_A8_BIT = 0x00010000, /* 8-32 argb bit/pixel, A=7:0, R=23:16, G=15:8, B=7:0 */ + AGL_RGB101010_BIT = 0x00020000, /* 32 rgb bit/pixel, R=29:20, G=19:10, B=9:0 */ + AGL_ARGB2101010_BIT = 0x00040000, /* 32 argb bit/pixel, A=31:30 R=29:20, G=19:10, B=9:0 */ + AGL_RGB101010_A8_BIT = 0x00080000, /* 8-32 argb bit/pixel, A=7:0 R=29:20, G=19:10, B=9:0 */ + AGL_RGB121212_BIT = 0x00100000, /* 48 rgb bit/pixel, R=35:24, G=23:12, B=11:0 */ + AGL_ARGB12121212_BIT = 0x00200000, /* 48 argb bit/pixel, A=47:36, R=35:24, G=23:12, B=11:0 */ + AGL_RGB161616_BIT = 0x00400000, /* 64 rgb bit/pixel, R=47:32, G=31:16, B=15:0 */ + AGL_ARGB16161616_BIT = 0x00800000, /* 64 argb bit/pixel, A=63:48, R=47:32, G=31:16, B=15:0 */ + AGL_INDEX8_BIT = 0x20000000, /* 8 bit color look up table (deprecated) */ + AGL_INDEX16_BIT = 0x40000000, /* 16 bit color look up table (deprecated) */ + AGL_RGBFLOAT64_BIT = 0x01000000, /* 64 rgb bit/pixel, half float */ + AGL_RGBAFLOAT64_BIT = 0x02000000, /* 64 argb bit/pixel, half float */ + AGL_RGBFLOAT128_BIT = 0x04000000, /* 128 rgb bit/pixel, ieee float */ + AGL_RGBAFLOAT128_BIT = 0x08000000, /* 128 argb bit/pixel, ieee float */ + AGL_RGBFLOAT256_BIT = 0x10000000, /* 256 rgb bit/pixel, ieee double */ + AGL_RGBAFLOAT256_BIT = 0x20000000, /* 256 argb bit/pixel, ieee double */ + } + /* + ** Error return values from aglGetError. + */ + internal enum AglError + { + NoError = 0, /* no error */ + + BadAttribute = 10000, /* invalid pixel format attribute */ + BadProperty = 10001, /* invalid renderer property */ + BadPixelFormat = 10002, /* invalid pixel format */ + BadRendererInfo = 10003, /* invalid renderer info */ + BadContext = 10004, /* invalid context */ + BadDrawable = 10005, /* invalid drawable */ + BadGraphicsDevice = 10006, /* invalid graphics device */ + BadState = 10007, /* invalid context state */ + BadValue = 10008, /* invalid numerical value */ + BadMatch = 10009, /* invalid share context */ + BadEnum = 10010, /* invalid enumerant */ + BadOffscreen = 10011, /* invalid offscreen drawable */ + BadFullscreen = 10012, /* invalid offscreen drawable */ + BadWindow = 10013, /* invalid window */ + BadPointer = 10014, /* invalid pointer */ + BadModule = 10015, /* invalid code module */ + BadAlloc = 10016, /* memory allocation failure */ + BadConnection = 10017, /* invalid CoreGraphics connection */ + } + /************************************************************************/ + + /* + ** Pixel format functions + */ + [DllImport(agl)] internal static extern AGLPixelFormat aglChoosePixelFormat(AGLDevice gdevs, int ndev, int []attribs); + [DllImport(agl)] internal static extern void aglDestroyPixelFormat(AGLPixelFormat pix); + [DllImport(agl)] internal static extern AGLPixelFormat aglNextPixelFormat(AGLPixelFormat pix); + [DllImport(agl)] static extern byte aglDescribePixelFormat(AGLPixelFormat pix, int attrib, out int value); + [Obsolete("Use aglDisplaysOfPixelFormat instead.")] + [DllImport(agl)] static extern AGLDevice *aglDevicesOfPixelFormat(AGLPixelFormat pix, int *ndevs); + + /* + ** Renderer information functions + */ + [DllImport(agl)] static extern AGLRendererInfo aglQueryRendererInfo(AGLDevice[] gdevs, int ndev); + [DllImport(agl)] static extern void aglDestroyRendererInfo(AGLRendererInfo rend); + [DllImport(agl)] static extern AGLRendererInfo aglNextRendererInfo(AGLRendererInfo rend); + [DllImport(agl)] static extern byte aglDescribeRenderer(AGLRendererInfo rend, int prop, out int value); + + /* + ** Context functions + */ + [DllImport(agl)] internal static extern AGLContext aglCreateContext(AGLPixelFormat pix, AGLContext share); + [DllImport(agl,EntryPoint="aglDestroyContext")] static extern byte _aglDestroyContext(AGLContext ctx); + internal static bool aglDestroyContext(AGLContext context) + { + return (_aglDestroyContext(context) != 0) ? true : false; + } + + [DllImport(agl)] static extern byte aglCopyContext(AGLContext src, AGLContext dst, uint mask); + [DllImport(agl)] internal static extern byte aglUpdateContext(AGLContext ctx); + + /* + ** Current state functions + */ + #region --- aglSetCurrentContext --- + + [DllImport(agl,EntryPoint="aglSetCurrentContext")] static extern byte _aglSetCurrentContext(AGLContext ctx); + internal static bool aglSetCurrentContext(IntPtr context) + { + byte retval = _aglSetCurrentContext(context); + + if (retval != 0) + return true; + else + return false; + } + + #endregion + + [DllImport(agl)] internal static extern AGLContext aglGetCurrentContext(); + + + /* + ** Drawable Functions + */ + [DllImport(agl)] internal static extern byte aglSetDrawable(AGLContext ctx, AGLDrawable draw); + [DllImport(agl)] static extern byte aglSetOffScreen(AGLContext ctx, int width, int height, int rowbytes, IntPtr baseaddr); + [DllImport(agl)] internal static extern byte aglSetFullScreen(AGLContext ctx, int width, int height, int freq, int device); + [DllImport(agl)] static extern AGLDrawable aglGetDrawable(AGLContext ctx); + + /* + ** Virtual screen functions + */ + [DllImport(agl)] static extern byte aglSetVirtualScreen(AGLContext ctx, int screen); + [DllImport(agl)] static extern int aglGetVirtualScreen(AGLContext ctx); + + /* + ** Obtain version numbers + */ + [DllImport(agl)] static extern void aglGetVersion(int *major, int *minor); + + /* + ** Global library options + */ + [DllImport(agl)] static extern byte aglConfigure(GLenum pname, uint param); + + /* + ** Swap functions + */ + [DllImport(agl)] internal static extern void aglSwapBuffers(AGLContext ctx); + + /* + ** Per context options + */ + [DllImport(agl)] internal static extern byte aglEnable(AGLContext ctx, ParameterNames pname); + [DllImport(agl)] internal static extern byte aglDisable(AGLContext ctx, ParameterNames pname); + [DllImport(agl)] static extern byte aglIsEnabled(AGLContext ctx, GLenum pname); + [DllImport(agl)] + internal static extern byte aglSetInteger(AGLContext ctx, ParameterNames pname, ref int @params); + [DllImport(agl)] + internal static extern byte aglSetInteger(AGLContext ctx, ParameterNames pname, int []@params); + [DllImport(agl)] + static extern byte aglGetInteger(AGLContext ctx, GLenum pname, int* @params); + + /* + ** Font function + */ + // TODO: face parameter should be of type StyleParameter in QuickDraw. + [DllImport(agl)] static extern byte aglUseFont(AGLContext ctx, int fontID, int face, int size, int first, int count, int @base); + + /* + ** Error functions + */ + [DllImport(agl,EntryPoint="aglGetError")] internal static extern AglError GetError(); + [DllImport(agl,EntryPoint="aglErrorString")] static extern IntPtr _aglErrorString(AglError code); + internal static string ErrorString(AglError code) + { + return Marshal.PtrToStringAnsi(_aglErrorString(code)); + } + + /* + ** Soft reset function + */ + [DllImport(agl)] static extern void aglResetLibrary(); + + /* + ** Surface texture function + */ + [DllImport(agl)] static extern void aglSurfaceTexture (AGLContext context, GLenum target, GLenum internalformat, AGLContext surfacecontext) ; + + /* + ** PBuffer functions + */ + [DllImport(agl)] static extern byte aglCreatePBuffer (int width, int height, GLenum target, GLenum internalFormat, long max_level, AGLPbuffer *pbuffer); + [DllImport(agl)] static extern byte aglDestroyPBuffer (AGLPbuffer pbuffer); + [DllImport(agl)] static extern byte aglDescribePBuffer (AGLPbuffer pbuffer, int *width, int *height, GLenum *target, GLenum *internalFormat, int *max_level); + [DllImport(agl)] static extern byte aglTexImagePBuffer (AGLContext ctx, AGLPbuffer pbuffer, int source); + + /* + ** Pbuffer Drawable Functions + */ + [DllImport(agl)] static extern byte aglSetPBuffer (AGLContext ctx, AGLPbuffer pbuffer, int face, int level, int screen) ; + [DllImport(agl)] static extern byte aglGetPBuffer (AGLContext ctx, AGLPbuffer *pbuffer, int *face, int *level, int *screen) ; + + /* + ** CGL functions + */ + [DllImport(agl)] static extern byte aglGetCGLContext(AGLContext ctx, void **cgl_ctx) ; + [DllImport(agl)] static extern byte aglGetCGLPixelFormat(AGLPixelFormat pix, void **cgl_pix); + + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs new file mode 100644 index 00000000..14d5eeee --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs @@ -0,0 +1,760 @@ +// +// +// Carbon.cs +// +// Created by Erik Ylvisaker on 3/17/08. +// Copyright 2008. All rights reserved. +// +// + +using System; +using System.Runtime.InteropServices; +using System.Diagnostics; + +namespace OpenTK.Platform.MacOS.Carbon +{ + + #region --- Types defined in MacTypes.h --- + + [StructLayout(LayoutKind.Sequential)] + internal struct Point + { + internal short V; + internal short H; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct Rect + { + internal short Top; + internal short Left; + internal short Bottom; + internal short Right; + + internal Rect(short _left, short _top, short _width, short _height) + { + Top = _top; + Left = _left; + Bottom = (short)(_top + _height); + Right = (short)(_left + _width); + } + + internal short Width { get { return (short)(Right - Left); } } + internal short Height { get { return (short)(Bottom - Top); } } + + public override string ToString() + { + return string.Format( + "Rect: [{0}, {1}, {2}, {3}]", Top, Left, Width, Height); + } + } + + #endregion + #region --- Types defined in HIGeometry.h --- + + [StructLayout(LayoutKind.Sequential)] + internal struct HIPoint + { + public float X; + public float Y; + } + [StructLayout(LayoutKind.Sequential)] + internal struct HISize + { + public float Width; + public float Height; + } + [StructLayout(LayoutKind.Sequential)] + internal struct HIRect + { + public HIPoint Origin; + public HISize Size; + + public override string ToString() + { + return string.Format( + "Rect: [{0}, {1}, {2}, {3}]", Origin.X, Origin.Y, Size.Width, Size.Height); + } + } + + #endregion + + #region --- Types defined in CarbonEvents.h --- + + [StructLayout(LayoutKind.Sequential)] + internal struct EventTypeSpec + { + internal EventTypeSpec(EventClass evtClass, AppEventKind evtKind) + { + this.EventClass = evtClass; + this.EventKind = (uint)evtKind; + } + internal EventTypeSpec(EventClass evtClass, AppleEventKind appleKind) + { + this.EventClass = evtClass; + this.EventKind = (uint)appleKind; + } + internal EventTypeSpec(EventClass evtClass, MouseEventKind evtKind) + { + this.EventClass = evtClass; + this.EventKind = (uint)evtKind; + } + internal EventTypeSpec(EventClass evtClass, KeyboardEventKind evtKind) + { + this.EventClass = evtClass; + this.EventKind = (uint)evtKind; + } + internal EventTypeSpec(EventClass evtClass, WindowEventKind evtKind) + { + this.EventClass = evtClass; + this.EventKind = (uint)evtKind; + } + + internal EventClass EventClass; + internal uint EventKind; + } + + public enum EventClass : int + { + /* + kEventClassMouse = FOUR_CHAR_CODE('mous'), + kEventClassKeyboard = FOUR_CHAR_CODE('keyb'), + kEventClassTextInput = FOUR_CHAR_CODE('text'), + kEventClassApplication = FOUR_CHAR_CODE('appl'), + kEventClassAppleEvent = FOUR_CHAR_CODE('eppc'), + kEventClassMenu = FOUR_CHAR_CODE('menu'), + kEventClassWindow = FOUR_CHAR_CODE('wind'), + kEventClassControl = FOUR_CHAR_CODE('cntl'), + kEventClassCommand = FOUR_CHAR_CODE('cmds') + */ + Mouse = 0x6d6f7573, + Keyboard = 0x6b657962, + Application = 0x6170706c, + AppleEvent = 0x65707063, + Menu = 0x6d656e75, + Window = 0x77696e64, + } + public enum WindowEventKind : int + { + // window events + WindowUpdate = 1, + WindowDrawContent = 2, + WindowDrawStructure = 3, + WindowEraseContent = 4, + WindowActivate = 5, + WindowDeactivate = 6, + WindowSizeChanged = 23, + WindowBoundsChanging = 26, + WindowBoundsChanged = 27, + WindowClickDragRgn = 32, + WindowClickResizeRgn = 33, + WindowClickCollapseRgn = 34, + WindowClickCloseRgn = 35, + WindowClickZoomRgn = 36, + WindowClickContentRgn = 37, + WindowClickProxyIconRgn = 38, + WindowClose = 72, + WindowClosed = 73, + } + public enum MouseEventKind : int + { + MouseDown = 1, + MouseUp = 2, + MouseMoved = 5, + MouseDragged = 6, + MouseEntered = 8, + MouseExited = 9, + WheelMoved = 10, + } + public enum MouseButton : short + { + Primary = 1, + Secondary = 2, + Tertiary = 3, + } + + public enum KeyboardEventKind : int + { + // raw keyboard events + RawKeyDown = 1, + RawKeyRepeat = 2, + RawKeyUp = 3, + RawKeyModifiersChanged = 4, + } + + public enum AppEventKind : int + { + // application events + AppActivated = 1, + AppDeactivated = 2, + AppQuit = 3, + AppLaunchNotification = 4, + } + + enum AppleEventKind : int + { + AppleEvent = 1, + } + + internal enum EventParamName : int + { + // Mouse Events + MouseLocation = 0x6d6c6f63, // typeHIPoint + WindowMouseLocation = 0x776d6f75, // typeHIPoint + MouseButton = 0x6d62746e, // typeMouseButton + ClickCount = 0x63636e74, // typeUInt32 + MouseWheelAxis = 0x6d776178, // typeMouseWheelAxis + MouseWheelDelta = 0x6d77646c, // typeSInt32 + MouseDelta = 0x6d647461, // typeHIPoint + + // Keyboard events + KeyCode = 0x6b636f64, // typeUInt32 + KeyMacCharCode = 0x6b636872, // typechar + KeyModifiers = 0x6b6d6f64, // typeUInt32 + + } + internal enum EventParamType : int + { + typeMouseButton = 0x6d62746e, + typeMouseWheelAxis = 0x6d776178, + typeHIPoint = 0x68697074, + typeHISize = 0x6869737a, + typeHIRect = 0x68697263, + + typeChar = 0x54455854, + + typeUInt32 = 0x6d61676e, + typeSInt32 = 0x6c6f6e67, + typeSInt16 = 0x73686f72, + typeSInt64 = 0x636f6d70, + typeIEEE32BitFloatingPoint = 0x73696e67, + typeIEEE64BitFloatingPoint = 0x646f7562, + } + + public enum EventMouseButton : int + { + Primary = 0, + Secondary = 1, + Tertiary = 2, + } + + internal enum WindowRegionCode : int + { + TitleBarRegion = 0, + TitleTextRegion = 1, + CloseBoxRegion = 2, + ZoomBoxRegion = 3, + DragRegion = 5, + GrowRegion = 6, + CollapseBoxRegion = 7, + TitleProxyIconRegion = 8, + StructureRegion = 32, + ContentRegion = 33, + UpdateRegion = 34, + OpaqueRegion = 35, + GlobalPortRegion = 40, + ToolbarButtonRegion = 41 + }; + + #endregion + + #region --- MacWindows.h --- + + internal enum WindowClass : uint + { + Alert = 1, /* "I need your attention now."*/ + MovableAlert = 2, /* "I need your attention now, but I'm kind enough to let you switch out of this app to do other things."*/ + Modal = 3, /* system modal, not draggable*/ + MovableModal = 4, /* application modal, draggable*/ + Floating = 5, /* floats above all other application windows*/ + Document = 6, /* document windows*/ + Desktop = 7, /* desktop window (usually only one of these exists) - OS X only in CarbonLib 1.0*/ + Utility = 8, /* Available in CarbonLib 1.1 and later, and in Mac OS X*/ + Help = 10, /* Available in CarbonLib 1.1 and later, and in Mac OS X*/ + Sheet = 11, /* Available in CarbonLib 1.3 and later, and in Mac OS X*/ + Toolbar = 12, /* Available in CarbonLib 1.1 and later, and in Mac OS X*/ + Plain = 13, /* Available in CarbonLib 1.2.5 and later, and Mac OS X*/ + Overlay = 14, /* Available in Mac OS X*/ + SheetAlert = 15, /* Available in CarbonLib 1.3 and later, and in Mac OS X 10.1 and later*/ + AltPlain = 16, /* Available in CarbonLib 1.3 and later, and in Mac OS X 10.1 and later*/ + Drawer = 20, /* Available in Mac OS X 10.2 or later*/ + All = 0xFFFFFFFFu /* for use with GetFrontWindowOfClass, FindWindowOfClass, GetNextWindowOfClass*/ + } + + [Flags] + internal enum WindowAttributes : uint + { + NoAttributes = 0u, /* no attributes*/ + CloseBox = (1u << 0), /* window has a close box*/ + HorizontalZoom = (1u << 1), /* window has horizontal zoom box*/ + VerticalZoom = (1u << 2), /* window has vertical zoom box*/ + FullZoom = (VerticalZoom | HorizontalZoom), + CollapseBox = (1u << 3), /* window has a collapse box*/ + Resizable = (1u << 4), /* window is resizable*/ + SideTitlebar = (1u << 5), /* window wants a titlebar on the side (floating window class only)*/ + NoUpdates = (1u << 16), /* this window receives no update events*/ + NoActivates = (1u << 17), /* this window receives no activate events*/ + NoBuffering = (1u << 20), /* this window is not buffered (Mac OS X only)*/ + StandardHandler = (1u << 25), + InWindowMenu = (1u << 27), + LiveResize = (1u << 28), + StandardDocument = (CloseBox | FullZoom | CollapseBox | Resizable), + StandardFloating = (CloseBox | CollapseBox) + } + + internal enum WindowPositionMethod : uint + { + CenterOnMainScreen = 1, + CenterOnParentWindow = 2, + CenterOnParentWindowScreen = 3, + CascadeOnMainScreen = 4, + CascadeOnParentWindow = 5, + CascadeOnParentWindowScreen = 6, + CascadeStartAtParentWindowScreen = 10, + AlertPositionOnMainScreen = 7, + AlertPositionOnParentWindow = 8, + AlertPositionOnParentWindowScreen = 9 + } + + internal delegate OSStatus MacOSEventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData); + + #endregion + + #region --- Carbon API Methods --- + + public partial class API + { + const string carbon = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon"; + + [DllImport(carbon)] + internal static extern EventClass GetEventClass(IntPtr inEvent); + [DllImport(carbon)] + internal static extern uint GetEventKind(IntPtr inEvent); + + #region --- Window Construction --- + + [DllImport(carbon,EntryPoint="CreateNewWindow")] + private static extern OSStatus _CreateNewWindow(WindowClass @class, WindowAttributes attributes, ref Rect r, out IntPtr window); + + internal static IntPtr CreateNewWindow(WindowClass @class, WindowAttributes attributes, Rect r) + { + IntPtr retval; + OSStatus stat = _CreateNewWindow(@class, attributes, ref r, out retval); + + Debug.Print("Created Window: {0}", retval); + + if (stat != OSStatus.NoError) + { + throw new MacOSException(stat); + } + + return retval; + } + + [DllImport(carbon)] + internal static extern void DisposeWindow(IntPtr window); + + #endregion + #region --- Showing / Hiding Windows --- + + [DllImport(carbon)] + internal static extern void ShowWindow(IntPtr window); + [DllImport(carbon)] + internal static extern void HideWindow(IntPtr window); + [DllImport(carbon)] + internal static extern bool IsWindowVisible(IntPtr window); + [DllImport(carbon)] + internal static extern void SelectWindow(IntPtr window); + + #endregion + #region --- Window Boundaries --- + + [DllImport(carbon)] + internal static extern OSStatus RepositionWindow(IntPtr window, IntPtr parentWindow, WindowPositionMethod method); + [DllImport(carbon)] + internal static extern void SizeWindow(IntPtr window, short w, short h, bool fUpdate); + + [DllImport(carbon)] + static extern OSStatus GetWindowBounds(IntPtr window, WindowRegionCode regionCode, out Rect globalBounds); + internal static Rect GetWindowBounds(IntPtr window, WindowRegionCode regionCode) + { + Rect retval; + OSStatus result = GetWindowBounds(window, regionCode, out retval); + + if (result != OSStatus.NoError) + throw new MacOSException(result); + + return retval; + } + + //[DllImport(carbon)] + //internal static extern void MoveWindow(IntPtr window, short hGlobal, short vGlobal, bool front); + + #endregion + #region --- Processing Events --- + + [DllImport(carbon)] + static extern IntPtr GetEventDispatcherTarget(); + + [DllImport(carbon,EntryPoint="ReceiveNextEvent")] + static extern OSStatus ReceiveNextEvent(uint inNumTypes, + IntPtr inList, + double inTimeout, + bool inPullEvent, + out IntPtr outEvent); + + [DllImport(carbon)] + static extern void SendEventToEventTarget(IntPtr theEvent, IntPtr theTarget); + + [DllImport(carbon)] + static extern void ReleaseEvent(IntPtr theEvent); + + // Processes events in the queue and then returns. + internal static void ProcessEvents() + { + IntPtr theEvent; + IntPtr theTarget = GetEventDispatcherTarget(); + + for (;;) + { + OSStatus status = ReceiveNextEvent(0, IntPtr.Zero, 0.0, true, out theEvent); + + if (status == OSStatus.EventLoopTimedOut) + break; + + if (status != OSStatus.NoError) + { + Debug.Print("Message Loop status: {0}", status); + break; + } + if (theEvent == IntPtr.Zero) + break; + + try + { + SendEventToEventTarget(theEvent, theTarget); + } + catch (System.ExecutionEngineException e) + { + Console.Error.WriteLine("ExecutionEngineException caught."); + Console.Error.WriteLine("theEvent: " + new EventInfo(theEvent).ToString()); + Console.Error.WriteLine(e.Message); + Console.Error.WriteLine(e.StackTrace); + } + + ReleaseEvent(theEvent); + } + + } + + #region --- Processing apple event --- + + [StructLayout(LayoutKind.Sequential)] + + struct EventRecord + { + public ushort what; + public uint message; + public uint when; + public Point where; + public uint modifiers; + } + + [DllImport(carbon)] + static extern bool ConvertEventRefToEventRecord(IntPtr inEvent, out EventRecord outEvent); + + [DllImport(carbon)] + static extern OSStatus AEProcessAppleEvent(ref EventRecord theEventRecord); + + static internal void ProcessAppleEvent(IntPtr inEvent) + { + EventRecord record; + + ConvertEventRefToEventRecord(inEvent, out record); + AEProcessAppleEvent(ref record); + } + + #endregion + + #endregion + #region --- Getting Event Parameters --- + + [DllImport(carbon)] + static extern OSStatus GetEventParameter( + IntPtr inEvent, EventParamName inName, EventParamType inDesiredType, + IntPtr outActualType, uint inBufferSize, IntPtr outActualSize, IntPtr outData); + + static internal MacOSKeyCode GetEventKeyboardKeyCode(IntPtr inEvent) + { + int code; + + unsafe + { + int* codeAddr = &code; + + OSStatus result = API.GetEventParameter(inEvent, + EventParamName.KeyCode, EventParamType.typeUInt32, IntPtr.Zero, + (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(UInt32)), IntPtr.Zero, + (IntPtr) codeAddr); + + if (result != OSStatus.NoError) + { + throw new MacOSException(result); + } + } + + return (MacOSKeyCode)code; + } + + internal static char GetEventKeyboardChar(IntPtr inEvent) + { + char code; + + unsafe + { + char* codeAddr = &code; + + OSStatus result = API.GetEventParameter(inEvent, + EventParamName.KeyMacCharCode, EventParamType.typeChar, IntPtr.Zero, + (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(char)), IntPtr.Zero, + (IntPtr)codeAddr); + + if (result != OSStatus.NoError) + { + throw new MacOSException(result); + } + } + + return code; + } + + static internal MouseButton GetEventMouseButton(IntPtr inEvent) + { + int button; + + unsafe + { + int* btn = &button; + + OSStatus result = API.GetEventParameter(inEvent, + EventParamName.MouseButton, EventParamType.typeMouseButton, IntPtr.Zero, + (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(short)), IntPtr.Zero, + (IntPtr)btn); + + if (result != OSStatus.NoError) + throw new MacOSException(result); + } + + return (MouseButton)button; + } + static internal HIPoint GetEventWindowMouseLocation(IntPtr inEvent) + { + HIPoint pt; + + unsafe + { + HIPoint* parm = &pt; + + OSStatus result = API.GetEventParameter(inEvent, + EventParamName.WindowMouseLocation, EventParamType.typeHIPoint, IntPtr.Zero, + (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(HIPoint)), IntPtr.Zero, + (IntPtr)parm); + + if (result != OSStatus.NoError) + throw new MacOSException(result); + } + + return pt; + } + static internal MacOSKeyModifiers GetEventKeyModifiers(IntPtr inEvent) + { + uint code; + + unsafe + { + uint* codeAddr = &code; + + OSStatus result = API.GetEventParameter(inEvent, + EventParamName.KeyModifiers, EventParamType.typeUInt32, IntPtr.Zero, + (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(uint)), IntPtr.Zero, + (IntPtr)codeAddr); + + if (result != OSStatus.NoError) + { + throw new MacOSException(result); + } + } + + return (MacOSKeyModifiers)code; + } + + #endregion + #region --- Event Handlers --- + + [DllImport(carbon,EntryPoint="InstallEventHandler")] + static extern OSStatus _InstallEventHandler( + IntPtr eventTargetRef, IntPtr handlerProc, + int numtypes, EventTypeSpec[] typeList, + IntPtr userData, IntPtr handlerRef); + + internal static void InstallWindowEventHandler(IntPtr windowRef, IntPtr uppHandlerProc, + EventTypeSpec[] eventTypes, IntPtr userData, IntPtr handlerRef) + { + IntPtr windowTarget = GetWindowEventTarget(windowRef); + + Debug.Print("Window: {0}", windowRef); + Debug.Print("Window Target: {0}", windowTarget); + Debug.Print("Handler: {0}", uppHandlerProc); + Debug.Print("Num Events: {0}", eventTypes.Length); + Debug.Print("User Data: {0}", userData); + Debug.Print("Handler Ref: {0}", handlerRef); + + OSStatus error = _InstallEventHandler(windowTarget, uppHandlerProc, + eventTypes.Length, eventTypes, + userData, handlerRef); + + Debug.Print("Status: {0}", error); + + if (error != OSStatus.NoError) + { + throw new MacOSException(error); + } + } + + internal static void InstallApplicationEventHandler(IntPtr uppHandlerProc, + EventTypeSpec[] eventTypes, IntPtr userData, IntPtr handlerRef) + { + OSStatus error = _InstallEventHandler(GetApplicationEventTarget(), uppHandlerProc, + eventTypes.Length, eventTypes, + userData, handlerRef); + + if (error != OSStatus.NoError) + { + throw new MacOSException(error); + } + + } + + [DllImport(carbon)] + internal static extern OSStatus RemoveEventHandler(IntPtr inHandlerRef); + + #endregion + #region --- GetWindowEventTarget --- + + [DllImport(carbon)] + internal static extern IntPtr GetWindowEventTarget(IntPtr window); + + [DllImport(carbon)] + internal static extern IntPtr GetApplicationEventTarget(); + + #endregion + #region --- UPP Event Handlers --- + + [DllImport(carbon)] + internal static extern IntPtr NewEventHandlerUPP(MacOSEventHandler handler); + + [DllImport(carbon)] + internal static extern void DisposeEventHandlerUPP(IntPtr userUPP); + + #endregion + + [DllImport(carbon)] + static extern IntPtr GetControlBounds(IntPtr control, out Rect bounds); + + internal static Rect GetControlBounds(IntPtr control) + { + Rect retval; + GetControlBounds(control, out retval); + + return retval; + } + + [DllImport(carbon)] + internal static extern OSStatus ActivateWindow (IntPtr inWindow, bool inActivate); + + [DllImport(carbon)] + internal static extern void RunApplicationEventLoop(); + + [DllImport(carbon)] + internal static extern void QuitApplicationEventLoop(); + + [DllImport(carbon)] + internal static extern IntPtr GetControlOwner(IntPtr control); + + [DllImport(carbon)] + internal static extern IntPtr HIViewGetWindow(IntPtr inView); + + [DllImport(carbon)] + static extern OSStatus HIViewGetFrame(IntPtr inView, out HIRect outRect); + internal static HIRect HIViewGetFrame(IntPtr inView) + { + HIRect retval; + OSStatus result = HIViewGetFrame(inView, out retval); + + if (result != OSStatus.NoError) + throw new MacOSException(result); + + return retval; + } + #region --- SetWindowTitle --- + + [DllImport(carbon)] + static extern void SetWindowTitleWithCFString(IntPtr windowRef, IntPtr title); + + internal static void SetWindowTitle(IntPtr windowRef, string title) + { + IntPtr str = __CFStringMakeConstantString(title); + + Debug.Print("Setting window title: {0}, CFstring : {1}, Text : {2}", windowRef, str, title); + + SetWindowTitleWithCFString(windowRef, str); + + // Apparently releasing this reference to the CFConstantString here + // causes the program to crash on the fourth window created. But I am + // afraid that not releasing the string would result in a memory leak, but that would + // only be a serious issue if the window title is changed a lot. + //CFRelease(str); + } + + #endregion + + [DllImport(carbon,EntryPoint="ChangeWindowAttributes")] + static extern OSStatus _ChangeWindowAttributes(IntPtr windowRef, WindowAttributes setTheseAttributes, WindowAttributes clearTheseAttributes); + internal static void ChangeWindowAttributes(IntPtr windowRef, WindowAttributes setTheseAttributes, WindowAttributes clearTheseAttributes) + { + OSStatus error = _ChangeWindowAttributes(windowRef, setTheseAttributes, clearTheseAttributes); + + if (error != OSStatus.NoError) + { + throw new MacOSException(error); + } + } + + [DllImport(carbon)] + static extern IntPtr __CFStringMakeConstantString(string cStr); + + [DllImport(carbon)] + static extern void CFRelease(IntPtr cfStr); + + [DllImport(carbon)] + internal static extern OSStatus CallNextEventHandler(IntPtr nextHandler, IntPtr theEvent); + + [DllImport(carbon)] + internal static extern IntPtr GetWindowPort(IntPtr windowRef); + + #region --- Menus --- + + [DllImport(carbon)] + internal static extern IntPtr AcquireRootMenu(); + + + #endregion + + + } + + #endregion + +} + + diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs new file mode 100644 index 00000000..58bdcb50 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs @@ -0,0 +1,116 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace OpenTK.Platform.MacOS.Carbon +{ + struct CFArray + { + IntPtr arrayRef; + public IntPtr Ref { get { return arrayRef; } set { arrayRef = value; } } + + public CFArray(IntPtr reference) + { + arrayRef = reference; + } + + public int Count + { + get { return CF.CFArrayGetCount(arrayRef); } + } + public IntPtr this[int index] + { + get + { + if (index >= Count || index < 0) + throw new IndexOutOfRangeException(); + + return CF.CFArrayGetValueAtIndex(arrayRef, index); + } + } + } + struct CFDictionary + { + public CFDictionary(IntPtr reference) + { + dictionaryRef = reference; + } + + IntPtr dictionaryRef; + public IntPtr Ref { get { return dictionaryRef; } set { dictionaryRef = value; } } + + public int Count + { + get + { + return CF.CFDictionaryGetCount(dictionaryRef); + } + } + public double GetNumberValue(string key) + { + unsafe + { + double retval; + IntPtr cfnum = CF.CFDictionaryGetValue(dictionaryRef, + CF.CFSTR(key)); + + CF.CFNumberGetValue(cfnum, CF.CFNumberType.kCFNumberDoubleType, &retval); + + return retval; + } + } + } + class CF + { + const string appServices = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices"; + + [DllImport(appServices)] + internal static extern int CFArrayGetCount(IntPtr theArray); + + [DllImport(appServices)] + internal static extern IntPtr CFArrayGetValueAtIndex(IntPtr theArray, int idx); + + [DllImport(appServices)] + internal static extern int CFDictionaryGetCount(IntPtr theDictionary); + + [DllImport(appServices)] + internal static extern IntPtr CFDictionaryGetValue(IntPtr theDictionary, IntPtr theKey); + + // this mirrors the definition in CFString.h. + // I don't know why, but __CFStringMakeConstantString is marked as "private and should not be used directly" + // even though the CFSTR macro just calls it. + [DllImport(appServices)] + static extern IntPtr __CFStringMakeConstantString(string cStr); + internal static IntPtr CFSTR(string cStr) + { + return __CFStringMakeConstantString(cStr); + } + + [DllImport(appServices)] + internal unsafe static extern bool CFNumberGetValue (IntPtr number, CFNumberType theType, int* valuePtr); + [DllImport(appServices)] + internal unsafe static extern bool CFNumberGetValue(IntPtr number, CFNumberType theType, double* valuePtr); + + internal enum CFNumberType + { + kCFNumberSInt8Type = 1, + kCFNumberSInt16Type = 2, + kCFNumberSInt32Type = 3, + kCFNumberSInt64Type = 4, + kCFNumberFloat32Type = 5, + kCFNumberFloat64Type = 6, + kCFNumberCharType = 7, + kCFNumberShortType = 8, + kCFNumberIntType = 9, + kCFNumberLongType = 10, + kCFNumberLongLongType = 11, + kCFNumberFloatType = 12, + kCFNumberDoubleType = 13, + kCFNumberCFIndexType = 14, + kCFNumberNSIntegerType = 15, + kCFNumberCGFloatType = 16, + kCFNumberMaxType = 16 + }; + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs new file mode 100644 index 00000000..070dc1ac --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenTK.Platform.MacOS.Carbon +{ + enum MacOSKeyCode + { + A = 0, + B = 11, + C = 8, + D = 2, + E = 14, + F = 3, + G = 5, + H = 4, + I = 34, + J = 38, + K = 40, + L = 37, + M = 46, + N = 45, + O = 31, + P = 35, + Q = 12, + R = 15, + S = 1, + T = 17, + U = 32, + V = 9, + W = 13, + X = 7, + Y = 16, + Z = 6, + + Key_1 = 18, + Key_2 = 19, + Key_3 = 20, + Key_4 = 21, + Key_5 = 23, + Key_6 = 22, + Key_7 = 26, + Key_8 = 28, + Key_9 = 25, + Key_0 = 29, + + Space = 49, + Tilde = 50, + + Minus = 27, + Equals = 24, + BracketLeft = 33, + BracketRight = 30, + Backslash = 42, + Semicolon = 41, + Quote = 39, + Comma = 43, + Period = 47, + Slash = 44, + + Enter = 36, + Tab = 48, + Backspace = 51, + Return = 52, + Esc = 53, + KeyPad_Decimal = 65, + KeyPad_Multiply = 67, + KeyPad_Add = 69, + KeyPad_Divide = 75, + KeyPad_Enter = 76, + KeyPad_Subtract = 78, + KeyPad_Equal = 81, + KeyPad_0 = 82, + KeyPad_1 = 83, + KeyPad_2 = 84, + KeyPad_3 = 85, + KeyPad_4 = 86, + KeyPad_5 = 87, + KeyPad_6 = 88, + KeyPad_7 = 89, + KeyPad_8 = 91, + KeyPad_9 = 92, + F1 = 122, + F2 = 120, + F3 = 99, + F4 = 118, + F5 = 96, + F6 = 97, + F7 = 98, + F8 = 100, + F9 = 101, + F10 = 109, + F11 = 103, + F12 = 111, + F13 = 105, + F14 = 107, + F15 = 113, + + Menu = 110, + + Insert = 114, + Home = 115, + Pageup = 116, + Del = 117, + End = 119, + Pagedown = 121, + Up = 126, + Down = 125, + Left = 123, + Right = 124, + + + } + [Flags] + enum MacOSKeyModifiers + { + None = 0, + Shift = 0x0200, + CapsLock = 0x0400, + Control = 0x1000, // + Command = 0x0100, // Open-Apple - Windows key + Option = 0x0800, // Option key is same position as the alt key on non-mac keyboards. + } + partial class API + { + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs new file mode 100644 index 00000000..4b8c0ece --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs @@ -0,0 +1,48 @@ +using System; +using System.Runtime.InteropServices; +using System.Diagnostics; + + +namespace OpenTK.Platform.MacOS.Carbon +{ + // Quartz Display services used here are available in MacOS X 10.3 and later. + + enum CGDisplayErr + { + + } + + public static class CG + { + const string appServices = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices"; + + // CGPoint -> HIPoint + // CGSize -> HISize + // CGRect -> HIRect + + [DllImport(appServices,EntryPoint="CGGetActiveDisplayList")] + internal static extern CGDisplayErr GetActiveDisplayList(int maxDisplays, IntPtr[] activeDspys, out int dspyCnt); + + [DllImport(appServices,EntryPoint="CGMainDisplayID")] + internal static extern IntPtr MainDisplayID(); + + [DllImport(appServices,EntryPoint="CGDisplayPixelsWide")] + internal static extern int DisplayPixelsWide(IntPtr display); + + [DllImport(appServices,EntryPoint="CGDisplayPixelsHigh")] + internal static extern int DisplayPixelsHigh(IntPtr display); + + [DllImport(appServices,EntryPoint="CGDisplayCurrentMode")] + internal static extern CFDictionary DisplayCurrentMode(IntPtr display); + + [DllImport(appServices,EntryPoint="CGDisplayCapture")] + internal static extern CGDisplayErr DisplayCapture(IntPtr display); + + [DllImport(appServices,EntryPoint="CGDisplayRelease")] + internal static extern CGDisplayErr DisplayRelease(IntPtr display); + + [DllImport(appServices, EntryPoint = "CGDisplayAvailableModes")] + internal static extern CFArray DisplayAvailableModes(IntPtr display); + + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/SpeechChannel.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/SpeechChannel.cs new file mode 100644 index 00000000..1be84963 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/SpeechChannel.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Text; + +namespace OpenTK.Platform.MacOS.Carbon +{ + + public class SpeechChannel + { + + private IntPtr _id; + + protected const string appServicesPath = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices"; + + [DllImport(appServicesPath)] + private static extern short NewSpeechChannel(IntPtr voice, ref IntPtr result); + + + [DllImport(appServicesPath)] + private static extern short SpeakText(IntPtr channel, String text, long length); + + public SpeechChannel() + { + short rc = NewSpeechChannel((IntPtr)null, ref _id); + Debug.WriteLine(rc); + } + + public bool Speak(String text) + { + short rc = SpeakText(_id, text, (long)text.Length); + return (rc == 0); + } + + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLControl.cs b/Source/OpenTK/Platform/MacOS/CarbonGLControl.cs new file mode 100644 index 00000000..90453285 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonGLControl.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Windows.Forms; + +namespace OpenTK.Platform.MacOS +{ + using Graphics; + + class CarbonGLControl : IGLControl + { + GraphicsMode mode; + Control control; + + internal CarbonGLControl(GraphicsMode mode, Control owner) + { + this.mode = mode; + this.control = owner; + } + + #region IGLControl Members + + public OpenTK.Graphics.GraphicsContext CreateContext() + { + return new GraphicsContext(mode, WindowInfo); + } + + public bool IsIdle + { + get { return true; } + } + + public IWindowInfo WindowInfo + { + get + { + control.CreateControl(); + return new CarbonWindowInfo(control.Handle, false, true); + } + } + + #endregion + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs new file mode 100644 index 00000000..6d53ca4b --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs @@ -0,0 +1,627 @@ +// +// +// xCSCarbon +// +// Created by Erik Ylvisaker on 3/17/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// +// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Text; + +namespace OpenTK.Platform.MacOS +{ + using Carbon; + using Graphics; + + class CarbonGLNative : INativeGLWindow + { + CarbonWindowInfo window; + CarbonInput mInputDriver; + GraphicsContext context; + + static MacOSKeyMap Keymap = new MacOSKeyMap(); + + IntPtr uppHandler; + string title = "New Window"; + short mWidth, mHeight; + bool mIsDisposed = false; + + WindowAttributes mWindowAttrib; + WindowClass mWindowClass; + WindowPositionMethod mPositionMethod = WindowPositionMethod.CenterOnMainScreen; + int mTitlebarHeight; + private WindowBorder windowBorder = WindowBorder.Resizable; + private WindowState windowState = WindowState.Normal; + + static Dictionary mWindows = new Dictionary(); + + static CarbonGLNative() + { + Application.Initialize(); + } + public CarbonGLNative() + : this(WindowClass.Document, + WindowAttributes.StandardDocument | + WindowAttributes.StandardHandler | + WindowAttributes.InWindowMenu | + WindowAttributes.LiveResize) + { + + } + private CarbonGLNative(WindowClass @class, WindowAttributes attrib) + { + mWindowClass = @class; + mWindowAttrib = attrib; + + + } + ~CarbonGLNative() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + protected virtual void Dispose(bool disposing) + { + if (mIsDisposed) + return; + + Debug.Print("Disposing of CarbonGLNative window."); + + mIsDisposed = true; + + if (disposing) + { + mWindows.Remove(window.WindowRef); + + window.Dispose(); + window = null; + } + + DisposeUPP(); + } + + private void DisposeUPP() + { + if (uppHandler != IntPtr.Zero) + { + // API.RemoveEventHandler(uppHandler); + // API.DisposeEventHandlerUPP(uppHandler); + + } + + uppHandler = IntPtr.Zero; + } + + + void CreateNativeWindow(WindowClass @class, WindowAttributes attrib, Rect r) + { + Debug.Print("Creating window..."); + Debug.Indent(); + + IntPtr windowRef = API.CreateNewWindow(@class, attrib, r); + //API.SetWindowTitle(windowRef, title); + + window = new CarbonWindowInfo(windowRef, true, false); + + SetSize(r.Width, r.Height); + + Debug.Unindent(); + Debug.Print("Created window."); + + mWindows.Add(windowRef, new WeakReference(this)); + + LoadSize(); + + Rect titleSize = API.GetWindowBounds(window.WindowRef, WindowRegionCode.TitleBarRegion); + mTitlebarHeight = titleSize.Height; + + Debug.Print("Titlebar size: {0}", titleSize); + + ConnectEvents(); + + System.Diagnostics.Debug.Print("Attached events."); + } + + public void Activate() + { + API.SelectWindow(window.WindowRef); + } + + void ConnectEvents() + { + mInputDriver = new CarbonInput(); + + EventTypeSpec[] eventTypes = new EventTypeSpec[] + { + new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClose), + new EventTypeSpec(EventClass.Window, WindowEventKind.WindowClosed), + new EventTypeSpec(EventClass.Window, WindowEventKind.WindowBoundsChanged), + + 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), + }; + + MacOSEventHandler handler = EventHandler; + uppHandler = API.NewEventHandlerUPP(handler); + + API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes, window.WindowRef, IntPtr.Zero); + } + + public string Title + { + get + { + return title; + } + set + { + API.SetWindowTitle(window.WindowRef, value); + title = value; + } + } + + public void Show() + { + IntPtr parent = IntPtr.Zero; + + API.ShowWindow(window.WindowRef); + API.RepositionWindow(window.WindowRef, parent, WindowPositionMethod); + API.SelectWindow(window.WindowRef); + + } + public void Hide() + { + API.HideWindow(window.WindowRef); + } + public bool Visible + { + get { return API.IsWindowVisible(window.WindowRef); } + set + { + if (value && Visible == false) + Show(); + else + Hide(); + } + } + public bool IsDisposed + { + get { return mIsDisposed; } + } + + + public WindowPositionMethod WindowPositionMethod + { + get { return mPositionMethod; } + set { mPositionMethod = value; } + } + + protected static OSStatus EventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData) + { + EventInfo evt = new EventInfo(inEvent); + WeakReference reference = mWindows[userData]; + CarbonGLNative window = (CarbonGLNative)reference.Target; + + + if (window == null) + { + Debug.WriteLine("Window for event not found."); + return OSStatus.EventNotHandled; + } + + switch(evt.EventClass) + { + case EventClass.Window: + return window.ProcessWindowEvent(inCaller, inEvent, evt, userData); + + case EventClass.Mouse: + return window.ProcessMouseEvent(inCaller, inEvent, evt, userData); + + case EventClass.Keyboard: + return window.ProcessKeyboardEvent(inCaller, inEvent, evt, userData); + + default: + return OSStatus.EventNotHandled; + } + + } + + private OSStatus ProcessKeyboardEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) + { + System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Keyboard); + MacOSKeyCode code; + char charCode; + + //Debug.Print(" {0}, '{1}'", (int)charCode, charCode); + + switch (evt.KeyboardEventKind) + { + case KeyboardEventKind.RawKeyRepeat: + GetCharCodes(inEvent, out code, out charCode); + InputDriver.Keyboard[0].KeyRepeat = true; + goto case KeyboardEventKind.RawKeyDown; + + case KeyboardEventKind.RawKeyDown: + GetCharCodes(inEvent, out code, out charCode); + Debug.Print(" {0}, '{1}'", code, charCode); + InputDriver.Keyboard[0][Keymap[code]] = true; + return OSStatus.EventNotHandled; + + case KeyboardEventKind.RawKeyUp: + GetCharCodes(inEvent, out code, out charCode); + InputDriver.Keyboard[0][Keymap[code]] = false; + + return OSStatus.EventNotHandled; + + case KeyboardEventKind.RawKeyModifiersChanged: + ProcessModifierKey(inEvent); + return OSStatus.EventNotHandled; + + default: + return OSStatus.EventNotHandled; + } + + + } + + private OSStatus ProcessWindowEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) + { + System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Window); + + switch(evt.WindowEventKind) + { + case WindowEventKind.WindowClose: + CancelEventArgs cancel = new CancelEventArgs(); + OnQueryWindowClose(cancel); + + if (cancel.Cancel) + return OSStatus.NoError; + else + return OSStatus.EventNotHandled; + + case WindowEventKind.WindowClosed: + OnWindowClosed(); + + return OSStatus.NoError; + + case WindowEventKind.WindowBoundsChanged: + OnResize(); + return OSStatus.EventNotHandled; + + default: + Debug.Print("{0}", evt); + + return OSStatus.EventNotHandled; + } + } + protected OSStatus ProcessMouseEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) + { + System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Mouse); + MouseButton button = MouseButton.Primary; + HIPoint pt = new HIPoint(); + + pt = API.GetEventWindowMouseLocation(inEvent); + + // ignore clicks in the title bar + if (pt.Y < mTitlebarHeight) + return OSStatus.EventNotHandled; + + // TODO: Fix this + //InputDriver.Mouse[0].X = (int)pt.X; + //InputDriver.Mouse[0].Y = (int)pt.Y - mTitlebarHeight; + + switch(evt.MouseEventKind) + { + case MouseEventKind.MouseDown: + button = API.GetEventMouseButton(inEvent); + + switch (button) + { + case MouseButton.Primary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = true; + break; + + case MouseButton.Secondary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = true; + break; + + case MouseButton.Tertiary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = true; + break; + } + + + break; + + case MouseEventKind.MouseUp: + switch (button) + { + case MouseButton.Primary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = false; + break; + + case MouseButton.Secondary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = false; + break; + + case MouseButton.Tertiary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = false; + break; + } + + button = API.GetEventMouseButton(inEvent); + + break; + + case MouseEventKind.MouseMoved: + case MouseEventKind.MouseDragged: + + //Debug.Print("MouseMoved: {0}", InputDriver.Mouse[0].Position); + + return OSStatus.EventNotHandled; + + default: + Debug.Print("{0}", evt); + + return OSStatus.EventNotHandled; + } + + return OSStatus.EventNotHandled; + } + + + private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode) + { + code = API.GetEventKeyboardKeyCode(inEvent); + charCode = API.GetEventKeyboardChar(inEvent); + } + private void ProcessModifierKey(IntPtr inEvent) + { + MacOSKeyModifiers modifiers = API.GetEventKeyModifiers(inEvent); + + bool caps = (modifiers & MacOSKeyModifiers.CapsLock) != 0 ? true : false; + bool control = (modifiers & MacOSKeyModifiers.Control) != 0 ? true : false; + bool command = (modifiers & MacOSKeyModifiers.Command) != 0 ? true : false; + bool option = (modifiers & MacOSKeyModifiers.Option) != 0 ? true : false; + bool shift = (modifiers & MacOSKeyModifiers.Shift) != 0 ? true : false; + + Debug.Print("Modifiers Changed: {0}", modifiers); + + Input.KeyboardDevice keyboard = InputDriver.Keyboard[0]; + + if (keyboard[OpenTK.Input.Key.AltLeft] ^ option) + keyboard[OpenTK.Input.Key.AltLeft] = option; + + if (keyboard[OpenTK.Input.Key.ShiftLeft] ^ shift) + keyboard[OpenTK.Input.Key.ShiftLeft] = shift; + + if (keyboard[OpenTK.Input.Key.WinLeft] ^ command) + keyboard[OpenTK.Input.Key.WinLeft] = command; + + if (keyboard[OpenTK.Input.Key.ControlLeft] ^ control) + keyboard[OpenTK.Input.Key.ControlLeft] = control; + + if (keyboard[OpenTK.Input.Key.CapsLock] ^ caps) + keyboard[OpenTK.Input.Key.CapsLock] = caps; + + } + + + Rect GetRegion() + { + Rect retval = API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); + + return retval; + } + + public int Width + { + get { return mWidth; } + set { SetSize(value, mHeight); } + } + public int Height + { + get { return mHeight; } + set { SetSize(mWidth, value); } + } + public void SetSize(int width, int height) + { + mWidth = (short)width; + mHeight = (short)height; + + API.SizeWindow(window.WindowRef, mWidth, mHeight, true); + + Rect contentBounds = API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); + + Rect newSize = new Rect(0, 0, + (short)(2 * mWidth - contentBounds.Width), + (short)(2 * mHeight - contentBounds.Height)); + + Debug.Print("Content region was: {0}", contentBounds); + Debug.Print("Resizing window to: {0}", newSize); + + API.SizeWindow(window.WindowRef, newSize.Width, newSize.Height, true); + + contentBounds = API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); + Debug.Print("New content region size: {0}", contentBounds); + + } + + protected void OnResize() + { + LoadSize(); + + if (context != null) + context.Update(window); + + if (Resize != null) + Resize(this, new ResizeEventArgs(Width, Height)); + } + + private void LoadSize() + { + Rect region = GetRegion(); + + mWidth = (short)(region.Right - region.Left); + mHeight = (short)(region.Bottom - region.Top); + } + + protected virtual void OnQueryWindowClose(CancelEventArgs e) + { + if (QueryWindowClose != null) + QueryWindowClose(this, e); + } + protected virtual void OnWindowClosed() + { + if (Destroy != null) + Destroy(this, EventArgs.Empty); + + } + + public event CancelEventHandler QueryWindowClose; + + + #region INativeGLWindow Members + + public void CreateWindow(int width, int height, OpenTK.Graphics.GraphicsMode mode, out OpenTK.Graphics.IGraphicsContext context) + { + Rect r = new Rect(0, 0, (short)width, (short)height); + CreateNativeWindow(mWindowClass, mWindowAttrib, r); + + Show(); + + this.context = new Graphics.GraphicsContext(mode, window); + this.context.MakeCurrent(window); + + context = this.context; + + } + + public void DestroyWindow() + { + Dispose(); + } + + public void ProcessEvents() + { + Application.ProcessEvents(); + } + + public void PointToClient(ref System.Drawing.Point p) + { + throw new Exception("The method or operation is not implemented."); + } + + public void PointToScreen(ref System.Drawing.Point p) + { + throw new Exception("The method or operation is not implemented."); + } + + public bool Exists + { + get { return !mIsDisposed; } + } + + public IWindowInfo WindowInfo + { + get { return window; } + } + + public bool IsIdle + { + get { return true; } + } + + public OpenTK.Input.IInputDriver InputDriver + { + get + { + return mInputDriver; + } + } + + public bool Fullscreen + { + get + { + return false; + } + set + { + throw new NotImplementedException(); + } + } + + public event CreateEvent Create; + + public event DestroyEvent Destroy; + + #endregion + + #region IResizable Members + + public event ResizeEvent Resize; + + #endregion + + #region INativeGLWindow Members + + + public WindowState WindowState + { + get + { + return windowState; + } + set + { + windowState = value; + } + } + + public WindowBorder WindowBorder + { + get + { + return windowBorder; + } + set + { + windowBorder = value; + + if (windowBorder == WindowBorder.Resizable) + { + API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.Resizable | WindowAttributes.FullZoom, + WindowAttributes.NoAttributes); + } + else if (windowBorder == WindowBorder.Fixed) + { + API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.NoAttributes, + WindowAttributes.Resizable | WindowAttributes.FullZoom); + } + } + } + + #endregion + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonInput.cs b/Source/OpenTK/Platform/MacOS/CarbonInput.cs new file mode 100644 index 00000000..01a886d2 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonInput.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +namespace OpenTK.Platform.MacOS +{ + using Input; + + class CarbonInput : IInputDriver + { + List dummy_keyboard_list = new List(1); + List dummy_mice_list = new List(1); + + internal CarbonInput() + { + dummy_mice_list.Add(new MouseDevice()); + dummy_keyboard_list.Add(new KeyboardDevice()); + + } + #region IInputDriver Members + + public void Poll() + { + } + + #endregion + + #region IKeyboardDriver Members + + public IList Keyboard + { + get { return dummy_keyboard_list; } + } + + #endregion + + #region IMouseDriver Members + + public IList Mouse + { + get { return dummy_mice_list; } + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + } + + #endregion + } +} diff --git a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs new file mode 100644 index 00000000..a46b3603 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenTK.Platform.MacOS +{ + sealed class CarbonWindowInfo : IWindowInfo + { + IntPtr windowRef; + bool ownHandle = false; + bool disposed = false; + bool isControl = false; + + internal CarbonWindowInfo(IntPtr windowRef, bool ownHandle, bool isControl) + { + this.windowRef = windowRef; + this.ownHandle = ownHandle; + this.isControl = isControl; + } + ~CarbonWindowInfo() + { + Dispose(false); + } + + internal IntPtr WindowRef + { + get { return this.windowRef; } + } + + public bool IsControl + { + get { return isControl; } + } + + /// Returns a System.String that represents the current window. + /// A System.String that represents the current window. + public override string ToString() + { + return String.Format("MacOS.CarbonWindowInfo: Handle {0}", + this.WindowRef); + } + + #region IDisposable Members + + public void Dispose() + { + Dispose(true); + } + + void Dispose(bool disposing) + { + if (disposed) + return; + + if (disposing) + { + + } + + if (ownHandle) + { + Carbon.API.DisposeWindow(this.windowRef); + windowRef = IntPtr.Zero; + } + + disposed = true; + } + + #endregion + } +} diff --git a/Source/OpenTK/Platform/MacOS/EventInfo.cs b/Source/OpenTK/Platform/MacOS/EventInfo.cs new file mode 100644 index 00000000..9216741f --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/EventInfo.cs @@ -0,0 +1,89 @@ +// +// +// xCSCarbon +// +// Created by Erik Ylvisaker on 3/17/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace OpenTK.Platform.MacOS.Carbon +{ + public struct EventInfo + { + internal EventInfo(IntPtr eventRef) + { + this._eventClass = API.GetEventClass(eventRef); + this._eventKind = API.GetEventKind(eventRef); + } + + uint _eventKind; + EventClass _eventClass; + + public EventClass EventClass { get { return _eventClass; }} + + public WindowEventKind WindowEventKind + { + get + { + if (EventClass == EventClass.Window) + return (WindowEventKind) _eventKind; + else + throw new InvalidCastException("Event is not a Window event."); + } + } + public KeyboardEventKind KeyboardEventKind + { + get + { + if (EventClass == EventClass.Keyboard) + return (KeyboardEventKind) _eventKind; + else + throw new InvalidCastException("Event is not a Keyboard event."); + } + } + public MouseEventKind MouseEventKind + { + get + { + if (EventClass == EventClass.Mouse) + return (MouseEventKind) _eventKind; + else + throw new InvalidCastException("Event is not an Mouse event."); + } + } + public AppEventKind AppEventKind + { + get + { + if (EventClass == EventClass.Application) + return (AppEventKind) _eventKind; + else + throw new InvalidCastException("Event is not an Application event."); + } + } + + + public override string ToString() + { + switch(EventClass) + { + case EventClass.Application: + return "Event: App " + AppEventKind.ToString(); + case EventClass.Keyboard: + return "Event: Keyboard " + KeyboardEventKind.ToString(); + case EventClass.Mouse: + return "Event: Mouse " + MouseEventKind.ToString(); + case EventClass.Window: + return "Event: Window " + WindowEventKind.ToString(); + } + + return "Event: Unknown Class " + EventClass.ToString() + " kind: " + _eventKind.ToString(); + } + } +} diff --git a/Source/OpenTK/Platform/MacOS/MacOSException.cs b/Source/OpenTK/Platform/MacOS/MacOSException.cs new file mode 100644 index 00000000..9ea1ad46 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/MacOSException.cs @@ -0,0 +1,92 @@ + +using System; + +namespace OpenTK.Platform.MacOS +{ + public class MacOSException : Exception + { + OSStatus errorCode; + + public MacOSException() + {} + public MacOSException(OSStatus errorCode) + : base("Error Code: " + errorCode.ToString()) + { + this.errorCode = errorCode; + } + public MacOSException(OSStatus errorCode, string message) + : base(message) + { + this.errorCode = errorCode; + } + + + public OSStatus ErrorCode + { + get { return errorCode; } + } + } + + public enum OSStatus + { + NoError = 0, + + ParameterError = -50, /*error in user parameter list*/ + NoHardwareError = -200, /*Sound Manager Error Returns*/ + NotEnoughHardwareError = -201, /*Sound Manager Error Returns*/ + UserCanceledError = -128, + QueueError = -1, /*queue element not found during deletion*/ + VTypErr = -2, /*invalid queue element*/ + CorErr = -3, /*core routine number out of range*/ + UnimpErr = -4, /*unimplemented core routine*/ + SlpTypeErr = -5, /*invalid queue element*/ + SeNoDB = -8, /*no debugger installed to handle debugger command*/ + ControlErr = -17, /*I/O System Errors*/ + StatusErr = -18, /*I/O System Errors*/ + ReadErr = -19, /*I/O System Errors*/ + WritErr = -20, /*I/O System Errors*/ + BadUnitErr = -21, /*I/O System Errors*/ + UnitEmptyErr = -22, /*I/O System Errors*/ + OpenErr = -23, /*I/O System Errors*/ + ClosErr = -24, /*I/O System Errors*/ + DRemovErr = -25, /*tried to remove an open driver*/ + DInstErr = -26, /*DrvrInstall couldn't find driver in resources*/ + + // Window Manager result codes. + InvalidWindowPtr = -5600, + UnsupportedWindowAttributesForClass = -5601, + WindowDoesNotHaveProxy = -5602, + WindowPropertyNotFound = -5604, + UnrecognizedWindowClass = -5605, + CorruptWindowDescription = -5606, + UserWantsToDragWindow = -5607, + WindowsAlreadyInitialized = -5608, + FloatingWindowsNotInitialized = -5609, + WindowNotFound = -5610, + WindowDoesNotFitOnscreen = -5611, + WindowAttributeImmutable = -5612, + WindowAttributesConflict = -5613, + WindowManagerInternalError = -5614, + WindowWrongState = -5615, + WindowGroupInvalid = -5616, + WindowAppModalStateAlreadyExists = -5617, + WindowNoAppModalState = -5618, + WindowDoesntSupportFocus = -30583, + WindowRegionCodeInvalid = -30593, + + // Event Manager result codes + EventAlreadyPosted = -9860, + EventTargetBusy = -9861, + EventDeferAccessibilityEvent = -9865, + EventInternalError = -9868, + EventParameterNotFound = -9870, + EventNotHandled = -9874, + EventLoopTimedOut = -9875, + EventLoopQuit = -9876, + EventNotInQueue = -9877, + HotKeyExists = -9878, + EventPassToNextTarget = -9880 + + } + +} diff --git a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs new file mode 100644 index 00000000..39a85c4e --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenTK.Platform.MacOS +{ + using Graphics; + + class MacOSFactory : IPlatformFactory + { + #region IPlatformFactory Members + + public INativeGLWindow CreateGLNative() + { + return new CarbonGLNative(); + } + + public IGLControl CreateGLControl(GraphicsMode mode, GLControl owner) + { + return new CarbonGLControl(mode, owner); + } + + public IDisplayDeviceDriver CreateDisplayDeviceDriver() + { + return new QuartzDisplayDeviceDriver(); + } + + public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool DirectRendering) + { + return new AglContext(mode, window, shareContext); + } + + public IGraphicsMode CreateGraphicsMode() + { + return new MacOSGraphicsMode(); + } + + #endregion + } +} diff --git a/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs b/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs new file mode 100644 index 00000000..30fcebc8 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenTK.Platform.MacOS +{ + using Graphics; + + class MacOSGraphicsMode : IGraphicsMode + { + #region IGraphicsMode Members + + 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, + accum, buffers, stereo); + + System.Diagnostics.Debug.Print("Created dummy graphics mode."); + + return gfx; + } + + #endregion + } +} diff --git a/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs b/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs new file mode 100644 index 00000000..b03d2e62 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenTK.Platform.MacOS +{ + using Carbon; + using Input; + + class MacOSKeyMap : Dictionary + { + public MacOSKeyMap() + { + // comments indicate members of the Key enum that are missing + + Add(MacOSKeyCode.A, Key.A); + // AltLeft + // AltRight + Add(MacOSKeyCode.B, Key.B); + + Add(MacOSKeyCode.Backslash, Key.BackSlash); + Add(MacOSKeyCode.Backspace, Key.BackSpace); + Add(MacOSKeyCode.BracketLeft, Key.BracketLeft); + Add(MacOSKeyCode.BracketRight, Key.BracketRight); + Add(MacOSKeyCode.C, Key.C); + // Capslock + // Clear + Add(MacOSKeyCode.Comma, Key.Comma); + // ControlLeft + // ControlRight + Add(MacOSKeyCode.D, Key.D); + Add(MacOSKeyCode.Del, Key.Delete); + Add(MacOSKeyCode.Down, Key.Down); + Add(MacOSKeyCode.E, Key.E); + Add(MacOSKeyCode.End, Key.End); + Add(MacOSKeyCode.Enter, Key.Enter); + Add(MacOSKeyCode.Return, Key.Enter); + Add(MacOSKeyCode.Esc, Key.Escape); + Add(MacOSKeyCode.F, Key.F); + Add(MacOSKeyCode.F1, Key.F1); + Add(MacOSKeyCode.F2, Key.F2); + Add(MacOSKeyCode.F3, Key.F3); + Add(MacOSKeyCode.F4, Key.F4); + Add(MacOSKeyCode.F5, Key.F5); + Add(MacOSKeyCode.F6, Key.F6); + Add(MacOSKeyCode.F7, Key.F7); + Add(MacOSKeyCode.F8, Key.F8); + Add(MacOSKeyCode.F9, Key.F9); + Add(MacOSKeyCode.F10, Key.F10); + Add(MacOSKeyCode.F11, Key.F11); + Add(MacOSKeyCode.F12, Key.F12); + Add(MacOSKeyCode.F13, Key.F13); + Add(MacOSKeyCode.F14, Key.F14); + Add(MacOSKeyCode.F15, Key.F15); + // F16-F35 + Add(MacOSKeyCode.G, Key.G); + Add(MacOSKeyCode.H, Key.H); + Add(MacOSKeyCode.Home, Key.Home); + Add(MacOSKeyCode.I, Key.I); + Add(MacOSKeyCode.Insert, Key.Insert); + Add(MacOSKeyCode.J, Key.J); + Add(MacOSKeyCode.K, Key.K); + Add(MacOSKeyCode.KeyPad_0, Key.Keypad0); + Add(MacOSKeyCode.KeyPad_1, Key.Keypad1); + Add(MacOSKeyCode.KeyPad_2, Key.Keypad2); + Add(MacOSKeyCode.KeyPad_3, Key.Keypad3); + Add(MacOSKeyCode.KeyPad_4, Key.Keypad4); + Add(MacOSKeyCode.KeyPad_5, Key.Keypad5); + Add(MacOSKeyCode.KeyPad_6, Key.Keypad6); + Add(MacOSKeyCode.KeyPad_7, Key.Keypad7); + Add(MacOSKeyCode.KeyPad_8, Key.Keypad8); + Add(MacOSKeyCode.KeyPad_9, Key.Keypad9); + Add(MacOSKeyCode.KeyPad_Add, Key.KeypadAdd); + Add(MacOSKeyCode.KeyPad_Decimal, Key.KeypadDecimal); + Add(MacOSKeyCode.KeyPad_Divide, Key.KeypadDivide); + Add(MacOSKeyCode.KeyPad_Enter, Key.KeypadEnter); + Add(MacOSKeyCode.KeyPad_Multiply, Key.KeypadMultiply); + Add(MacOSKeyCode.KeyPad_Subtract, Key.KeypadSubtract); + //Add(MacOSKeyCode.KeyPad_Equal); + Add(MacOSKeyCode.L, Key.L); + Add(MacOSKeyCode.Left, Key.Left); + Add(MacOSKeyCode.M, Key.M); + //Key.MaxKeys + Add(MacOSKeyCode.Menu, Key.Menu); + Add(MacOSKeyCode.Minus, Key.Minus); + Add(MacOSKeyCode.N, Key.N); + Add(MacOSKeyCode.Key_0, Key.Number0); + Add(MacOSKeyCode.Key_1, Key.Number1); + Add(MacOSKeyCode.Key_2, Key.Number2); + Add(MacOSKeyCode.Key_3, Key.Number3); + Add(MacOSKeyCode.Key_4, Key.Number4); + Add(MacOSKeyCode.Key_5, Key.Number4); + Add(MacOSKeyCode.Key_6, Key.Number5); + Add(MacOSKeyCode.Key_7, Key.Number6); + Add(MacOSKeyCode.Key_8, Key.Number7); + Add(MacOSKeyCode.Key_9, Key.Number9); + // Numlock + Add(MacOSKeyCode.O, Key.O); + Add(MacOSKeyCode.P, Key.P); + Add(MacOSKeyCode.Pagedown, Key.PageDown); + Add(MacOSKeyCode.Pageup, Key.PageUp); + // Pause + Add(MacOSKeyCode.Period, Key.Period); + Add(MacOSKeyCode.Equals, Key.Plus); + // PrintScreen + Add(MacOSKeyCode.Q, Key.Q); + Add(MacOSKeyCode.Quote, Key.Quote); + Add(MacOSKeyCode.R, Key.R); + Add(MacOSKeyCode.Right, Key.Right); + Add(MacOSKeyCode.S, Key.S); + // ScrollLock + Add(MacOSKeyCode.Semicolon, Key.Semicolon); + //Key.ShiftLeft + //Key.ShiftRight + Add(MacOSKeyCode.Slash, Key.Slash); + // Key.Sleep + Add(MacOSKeyCode.Space, Key.Space); + Add(MacOSKeyCode.T, Key.T); + Add(MacOSKeyCode.Tab, Key.Tab); + Add(MacOSKeyCode.Tilde, Key.Tilde); + Add(MacOSKeyCode.U, Key.U); + Add(MacOSKeyCode.Up, Key.Up); + Add(MacOSKeyCode.V, Key.V); + Add(MacOSKeyCode.W, Key.W); + // WinKeyLeft + // WinKeyRight + Add(MacOSKeyCode.X, Key.X); + Add(MacOSKeyCode.Y, Key.Y); + Add(MacOSKeyCode.Z, Key.Z); + + } + } +} diff --git a/Source/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs b/Source/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs new file mode 100644 index 00000000..4eb21c02 --- /dev/null +++ b/Source/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +namespace OpenTK.Platform.MacOS +{ + using Graphics; + using Carbon; + + class QuartzDisplayDeviceDriver : IDisplayDeviceDriver + { + static object display_lock = new object(); + + static QuartzDisplayDeviceDriver() + { + //lock (display_lock) + //{ + // List resolutions = new List(); + + // DisplayResolution primaryRes = new DisplayResolution(1024, 768, 32, 60); + // resolutions.Add(primaryRes); + + // object o = new Graphics.DisplayDevice(primaryRes, true, resolutions); + //} + + lock (display_lock) + { + // To minimize the need to add static methods to OpenTK.Graphics.DisplayDevice + // we only allow settings to be set through its constructor. + // Thus, we save all necessary parameters in temporary variables + // and construct the device when every needed detail is available. + // The main DisplayDevice constructor adds the newly constructed device + // to the list of available devices. + const int maxDisplayCount = 20; + IntPtr[] displays = new IntPtr[maxDisplayCount]; + int displayCount; + + CG.GetActiveDisplayList(maxDisplayCount, displays, out displayCount); + + Debug.Print("CoreGraphics reported {0} displays.", displayCount); + Debug.Indent(); + + for (int i = 0; i < displayCount; i++) + { + IntPtr currentDisplay = displays[i]; + + // according to docs, first element in the array is always the + // main display. + bool primary = (i == 0); + + // gets current settings + int currentWidth = CG.DisplayPixelsWide(currentDisplay); + int currentHeight = CG.DisplayPixelsHigh(currentDisplay); + Debug.Print("Display {0} is at {1}x{2}", i, currentWidth, currentHeight); + + CFArray displayModes = CG.DisplayAvailableModes(currentDisplay); + Debug.Print("Supports {0} display modes.", displayModes.Count); + + DisplayResolution opentk_dev_current_res = null; + List opentk_dev_available_res = new List(); + CFDictionary currentMode = CG.DisplayCurrentMode(currentDisplay); + + for (int j = 0; j < displayModes.Count; j++) + { + CFDictionary dict = new CFDictionary(displayModes[j]); + + int width = (int) dict.GetNumberValue("Width"); + int height = (int) dict.GetNumberValue("Height"); + int bpp = (int) dict.GetNumberValue("BitsPerPixel"); + double freq = dict.GetNumberValue("RefreshRate"); + bool current = currentMode.Ref == dict.Ref; + + //if (current) Debug.Write(" * "); + //else Debug.Write(" "); + + //Debug.Print("Mode {0} is {1}x{2}x{3} @ {4}.", j, width, height, bpp, freq); + + DisplayResolution thisRes = new DisplayResolution(width, height, bpp, (float)freq); + opentk_dev_available_res.Add(thisRes); + + if (current) + opentk_dev_current_res = thisRes; + + } + + OpenTK.Graphics.DisplayDevice opentk_dev = + new DisplayDevice(opentk_dev_current_res, primary, opentk_dev_available_res); + } + + Debug.Unindent(); + } + } + + #region IDisplayDeviceDriver Members + + public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution) + { + + return false; + } + + public bool TryRestoreResolution(DisplayDevice device) + { + return false; + } + + #endregion + } +} diff --git a/Source/OpenTK/Platform/OSX/Functions.cs b/Source/OpenTK/Platform/OSX/Functions.cs deleted file mode 100644 index 2c68e307..00000000 --- a/Source/OpenTK/Platform/OSX/Functions.cs +++ /dev/null @@ -1,29 +0,0 @@ -#region --- License --- -/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos - * See license.txt for license info - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; - -namespace OpenTK.Platform.OSX -{ - public static partial class Functions - { - internal const string Library = "libdl.dylib"; - - #region OSX GetProcAddress - - [DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")] - internal static extern bool NSIsSymbolNameDefined(string s); - [DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")] - internal static extern IntPtr NSLookupAndBindSymbol(string s); - [DllImport(Library, EntryPoint = "NSAddressOfSymbol")] - internal static extern IntPtr NSAddressOfSymbol(IntPtr symbol); - - #endregion - } -} diff --git a/Source/OpenTK/Platform/Utilities.cs b/Source/OpenTK/Platform/Utilities.cs index db54a4ce..e107aa5f 100644 --- a/Source/OpenTK/Platform/Utilities.cs +++ b/Source/OpenTK/Platform/Utilities.cs @@ -265,7 +265,7 @@ namespace OpenTK.Platform { if (Configuration.RunningOnWindows) return CreateWinWindowInfo(controlHandle); else if (Configuration.RunningOnX11) return CreateX11WindowInfo(mode, controlHandle); - else if (Configuration.RunningOnOSX) return CreateOSXWindowInfo(controlHandle); + else if (Configuration.RunningOnMacOS) return CreateOSXWindowInfo(controlHandle); else throw new PlatformNotSupportedException("Refer to http://www.opentk.com for more information."); } diff --git a/Source/OpenTK/Platform/Windows/WinGLContext.cs b/Source/OpenTK/Platform/Windows/WinGLContext.cs index de2cb30e..1db572d6 100644 --- a/Source/OpenTK/Platform/Windows/WinGLContext.cs +++ b/Source/OpenTK/Platform/Windows/WinGLContext.cs @@ -208,6 +208,13 @@ namespace OpenTK.Platform.Windows #endregion + #region public void Update + public void Update(IWindowInfo window) + { + } + #endregion + + public event DestroyEvent Destroy; #endregion @@ -435,6 +442,12 @@ namespace OpenTK.Platform.Windows #endregion + #endregion + + #region IGraphicsContext Members + + + #endregion } } diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index 8873e98f..052aa834 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -235,6 +235,12 @@ namespace OpenTK.Platform.X11 #endregion + #region public void Update + public void Update(IWindowInfo window) + { + } + #endregion + public void RegisterForDisposal(IDisposable resource) { throw new NotSupportedException("Use OpenTK.GraphicsContext instead.");