* EventInfo.cs:

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

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

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

View file

@ -6,20 +6,19 @@ namespace OpenTK.Platform.MacOS
{
using Graphics;
class MacOSGraphicsMode : IGraphicsMode
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);
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

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

View file

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