Initial commit with Mac OS support.

This commit is contained in:
kanato 2008-11-04 18:35:17 +00:00
parent 7b1c546abd
commit 8b65201145
34 changed files with 3392 additions and 81 deletions

View file

@ -21,7 +21,7 @@ namespace OpenTK
/// <summary>Contains configuration options for OpenTK.</summary>
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
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on an X11 platform.</summary>
internal static bool RunningOnX11 { get { return runningOnX11; } }
@ -81,10 +81,10 @@ namespace OpenTK
#endregion
#region internal static bool RunningOnOSX
#region internal static bool RunningOnMacOS
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on an OSX platform.</summary>
internal static bool RunningOnOSX { get { return runningOnOSX; } }
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on a Mac OS platform.</summary>
internal static bool RunningOnMacOS { get { return runningOnMacOS; } }
#endregion

View file

@ -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 ---
/// <summary>Raises the HandleCreated event.</summary>

View file

@ -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
/// <summary>Stops the main loop.</summary>
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)
{

View file

@ -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;

View file

@ -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.");
}
}

View file

@ -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 ---

View file

@ -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

View file

@ -44,6 +44,13 @@ namespace OpenTK.Graphics
/// Gets or sets a value indicating whether VSyncing is enabled.
/// </summary>
bool VSync { get; set; }
/// <summary>
/// Updates the graphics context. This must be called when the region the graphics context
/// is drawn to is resized.
/// </summary>
/// <param name="window"></param>
void Update(IWindowInfo window);
}
public delegate void DestroyEvent<T>(T sender, EventArgs e);

View file

@ -3,4 +3,6 @@
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.0"/>
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
</configuration>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
</configuration>

View file

@ -87,5 +87,14 @@ namespace OpenTK.Platform
}
#endregion
#region IGraphicsContext Members
public void Update(IWindowInfo window)
{
}
#endregion
}
}

View file

@ -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
}
}
}

View file

@ -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();
}
}

View file

@ -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<IGraphicsContext> 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
}
}

View file

@ -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();
}
}
}

View file

@ -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);
}
}

View file

@ -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
}

View file

@ -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
};
}
}

View file

@ -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
{
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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
}
}

View file

@ -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<IntPtr, WeakReference> mWindows = new Dictionary<IntPtr, WeakReference>();
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
}
}

View file

@ -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<KeyboardDevice> dummy_keyboard_list = new List<KeyboardDevice>(1);
List<MouseDevice> dummy_mice_list = new List<MouseDevice>(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<KeyboardDevice> Keyboard
{
get { return dummy_keyboard_list; }
}
#endregion
#region IMouseDriver Members
public IList<MouseDevice> Mouse
{
get { return dummy_mice_list; }
}
#endregion
#region IDisposable Members
public void Dispose()
{
}
#endregion
}
}

View file

@ -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; }
}
/// <summary>Returns a System.String that represents the current window.</summary>
/// <returns>A System.String that represents the current window.</returns>
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
}
}

View file

@ -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();
}
}
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -0,0 +1,133 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Platform.MacOS
{
using Carbon;
using Input;
class MacOSKeyMap : Dictionary<MacOSKeyCode, Key>
{
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);
}
}
}

View file

@ -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<DisplayResolution> resolutions = new List<DisplayResolution>();
// 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<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
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
}
}

View file

@ -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
}
}

View file

@ -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.");
}

View file

@ -208,6 +208,13 @@ namespace OpenTK.Platform.Windows
#endregion
#region public void Update
public void Update(IWindowInfo window)
{
}
#endregion
public event DestroyEvent<IGraphicsContext> Destroy;
#endregion
@ -435,6 +442,12 @@ namespace OpenTK.Platform.Windows
#endregion
#endregion
#region IGraphicsContext Members
#endregion
}
}

View file

@ -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.");