From cdd88e6f7eb91c9f617ac767a759f74d5a41fbd8 Mon Sep 17 00:00:00 2001 From: thefiddler Date: Thu, 24 Apr 2014 01:14:40 +0200 Subject: [PATCH] [Mac] Migrated AglContext to OpenTK.GLControl --- .../MacOS/CarbonBindings => GLControl}/Agl.cs | 5 +- .../MacOS => GLControl}/AglContext.cs | 373 +++--- .../AglGraphicsMode.cs} | 124 +- Source/GLControl/Carbon.cs | 160 +++ Source/GLControl/CarbonGLControl.cs | 6 +- Source/GLControl/NS.cs | 113 ++ Source/GLControl/OpenTK.GLControl.csproj | 16 + Source/OpenTK/OpenTK.csproj | 53 +- Source/OpenTK/Platform/MacOS/Application.cs | 27 - .../{CarbonBindings => Carbon}/CarbonAPI.cs | 0 .../MacOS/{CarbonBindings => Carbon}/Cgl.cs | 0 .../CoreFoundation.cs | 0 .../{CarbonBindings => Carbon}/MacOSKeys.cs | 0 .../QuartzDisplayServicesAPI.cs | 0 .../SpeechChannel.cs | 0 .../OpenTK/Platform/MacOS/CarbonGLNative.cs | 1147 ----------------- Source/OpenTK/Platform/MacOS/CarbonInput.cs | 122 -- .../OpenTK/Platform/MacOS/CarbonWindowInfo.cs | 9 +- .../OpenTK/Platform/MacOS/MacOSException.cs | 2 +- Source/OpenTK/Platform/Utilities.cs | 10 + 20 files changed, 567 insertions(+), 1600 deletions(-) rename Source/{OpenTK/Platform/MacOS/CarbonBindings => GLControl}/Agl.cs (99%) rename Source/{OpenTK/Platform/MacOS => GLControl}/AglContext.cs (52%) rename Source/{OpenTK/Platform/MacOS/MacOSGraphicsMode.cs => GLControl/AglGraphicsMode.cs} (73%) create mode 100644 Source/GLControl/Carbon.cs create mode 100644 Source/GLControl/NS.cs rename Source/OpenTK/Platform/MacOS/{CarbonBindings => Carbon}/CarbonAPI.cs (100%) rename Source/OpenTK/Platform/MacOS/{CarbonBindings => Carbon}/Cgl.cs (100%) rename Source/OpenTK/Platform/MacOS/{CarbonBindings => Carbon}/CoreFoundation.cs (100%) rename Source/OpenTK/Platform/MacOS/{CarbonBindings => Carbon}/MacOSKeys.cs (100%) rename Source/OpenTK/Platform/MacOS/{CarbonBindings => Carbon}/QuartzDisplayServicesAPI.cs (100%) rename Source/OpenTK/Platform/MacOS/{CarbonBindings => Carbon}/SpeechChannel.cs (100%) delete mode 100644 Source/OpenTK/Platform/MacOS/CarbonGLNative.cs delete mode 100644 Source/OpenTK/Platform/MacOS/CarbonInput.cs diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs b/Source/GLControl/Agl.cs similarity index 99% rename from Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs rename to Source/GLControl/Agl.cs index 11197a7f..560aebda 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs +++ b/Source/GLControl/Agl.cs @@ -377,8 +377,7 @@ namespace OpenTK.Platform.MacOS if (retval == 0) { AglError err = GetError(); - - throw new MacOSException(err, ErrorString(err)); + throw new Exception(ErrorString(err)); } } [DllImport(agl)] static extern byte aglSetOffScreen(AGLContext ctx, int width, int height, int rowbytes, IntPtr baseaddr); @@ -398,7 +397,7 @@ namespace OpenTK.Platform.MacOS Debug.Print(ErrorString(err)); Debug.Unindent(); - throw new MacOSException(err, ErrorString(err)); + throw new Exception(ErrorString(err)); } } /* diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/GLControl/AglContext.cs similarity index 52% rename from Source/OpenTK/Platform/MacOS/AglContext.cs rename to Source/GLControl/AglContext.cs index ed42bc93..ee2a834f 100644 --- a/Source/OpenTK/Platform/MacOS/AglContext.cs +++ b/Source/GLControl/AglContext.cs @@ -42,318 +42,199 @@ namespace OpenTK.Platform.MacOS using AGLContext = IntPtr; using AGLPbuffer = IntPtr; - class AglContext : DesktopGraphicsContext + /// + /// AGL context implementation for WinForms compatibility. + /// + class AglContext : IGraphicsContext, IGraphicsContextInternal { - // Todo: keep track of which display adapter was specified when the context was created. - // IntPtr displayID; + ContextHandle Handle; + GraphicsMode mode; + IWindowInfo carbonWindow; + IGraphicsContext dummyContext; // for extension loading + bool disposed; + bool error_checking; - CarbonWindowInfo carbonWindow; - IntPtr shareContextRef; - bool mIsFullscreen = false; + readonly GetInt XOffset; + readonly GetInt YOffset; - public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext) + public AglContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, + GetInt xoffset, GetInt yoffset) { - Debug.Print("Context Type: {0}", shareContext); + Debug.Print("Share context: {0}", shareContext); Debug.Print("Window info: {0}", window); + IntPtr shareContextRef = IntPtr.Zero; + + XOffset = xoffset; + YOffset = yoffset; + + carbonWindow = window; - this.carbonWindow = (CarbonWindowInfo)window; - if (shareContext is AglContext) + { shareContextRef = ((AglContext)shareContext).Handle.Handle; - if (shareContext is GraphicsContext) + } + else 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); } - public AglContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext) - { - if (handle == ContextHandle.Zero) - throw new ArgumentException("handle"); - if (window == null) - throw new ArgumentNullException("window"); - - Handle = handle; - carbonWindow = (CarbonWindowInfo)window; - } - - private void AddPixelAttrib(List aglAttributes, Agl.PixelFormatAttribute pixelFormatAttribute) { Debug.Print(pixelFormatAttribute.ToString()); - + aglAttributes.Add((int)pixelFormatAttribute); } + private void AddPixelAttrib(List 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, IWindowInfo carbonWindow, IntPtr shareContextRef, bool fullscreen) { Debug.Print("AGL pixel format attributes:"); - - AGLPixelFormat myAGLPixelFormat; - - // Choose a pixel format with the attributes we specified. - IntPtr gdevice; - IntPtr cgdevice = GetQuartzDevice(carbonWindow); - - if (cgdevice == IntPtr.Zero) - cgdevice = (IntPtr)DisplayDevice.Default.Id; - - OSStatus status = Carbon.API.DMGetGDeviceByDisplayID(cgdevice, out gdevice, false); - - if (status != OSStatus.NoError) - throw new MacOSException(status, "DMGetGDeviceByDisplayID failed."); - IGraphicsMode selector = new MacOSGraphicsMode(gdevice); + + // Choose a pixel format with the attributes we specified. + AGLPixelFormat pixelformat; + AglGraphicsMode selector = new AglGraphicsMode(); Mode = selector.SelectGraphicsMode( mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, - mode.AccumulatorFormat, mode.Buffers, mode.Stereo); + mode.AccumulatorFormat, mode.Buffers, mode.Stereo, + out pixelformat); MyAGLReportError("aglChoosePixelFormat"); Debug.Print("Creating AGL context. Sharing with {0}", shareContextRef); - myAGLPixelFormat = Mode.Index.Value; - // create the context and share it with the share reference. - Handle = new ContextHandle(Agl.aglCreateContext(myAGLPixelFormat, shareContextRef)); + Handle = new ContextHandle(Agl.aglCreateContext(pixelformat, shareContextRef)); MyAGLReportError("aglCreateContext"); // Free the pixel format from memory. - Agl.aglDestroyPixelFormat(myAGLPixelFormat); + Agl.aglDestroyPixelFormat(pixelformat); MyAGLReportError("aglDestroyPixelFormat"); - - Debug.Print("IsControl: {0}", carbonWindow.IsControl); - + SetDrawable(carbonWindow); SetBufferRect(carbonWindow); Update(carbonWindow); - + MakeCurrent(carbonWindow); Debug.Print("context: {0}", Handle.Handle); + + dummyContext = new GraphicsContext(Handle, + GetAddress, + delegate() + { + return new ContextHandle(Agl.aglGetCurrentContext()); + }); } - private IntPtr GetQuartzDevice(CarbonWindowInfo carbonWindow) + void SetBufferRect(IWindowInfo carbonWindow) { - IntPtr windowRef = carbonWindow.Handle; - - 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); - - } + Rect rect = API.GetControlBounds(carbonWindow.Handle); - void SetBufferRect(CarbonWindowInfo carbonWindow) - { - if (carbonWindow.IsControl == false) - return; - - Rect rect = API.GetControlBounds(carbonWindow.WindowHandle); - Debug.Print("Setting buffer_rect for control."); Debug.Print("MacOS Coordinate Rect: {0}", rect); int[] glrect = new int[4]; - if (carbonWindow.XOffset != null) - glrect[0] = rect.X + carbonWindow.XOffset(); + if (XOffset != null) + glrect[0] = rect.X + XOffset(); else glrect[0] = rect.X; - if (carbonWindow.YOffset != null) - glrect[1] = rect.Y + carbonWindow.YOffset(); + if (YOffset != null) + glrect[1] = rect.Y + YOffset(); else 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) + + void SetDrawable(IWindowInfo carbonWindow) { IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow); //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) + private static IntPtr GetWindowPortForWindowInfo(IWindowInfo carbonWindow) { IntPtr windowPort; - if (carbonWindow.IsControl) - { - IntPtr controlOwner = API.GetControlOwner(carbonWindow.Handle); - - windowPort = API.GetWindowPort(controlOwner); - } - else - { - windowPort = API.GetWindowPort(carbonWindow.Handle); - } + IntPtr controlOwner = API.GetControlOwner(carbonWindow.Handle); + windowPort = API.GetWindowPort(controlOwner); return windowPort; } - 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; - } - 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); - + public void Update(IWindowInfo window) + { + SetDrawable(window); + SetBufferRect(window); + Agl.aglUpdateContext(Handle.Handle); } - private CarbonGLNative GetCarbonWindow(CarbonWindowInfo carbonWindow) - { - WeakReference r = CarbonGLNative.WindowRefMap[carbonWindow.Handle]; - - if (r.IsAlive) - { - return (CarbonGLNative)r.Target; - } - - 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 Exception(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; - - // 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; - } - internal void UnsetFullScreen(CarbonWindowInfo windowInfo) - { - 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; - } - - #region IGraphicsContext Members - bool firstSwap = false; - public override void SwapBuffers() + bool firstSwap = true; + public void SwapBuffers() { // this is part of the hack to avoid dropping the first frame when // using multiple GLControls. - if (firstSwap == false && carbonWindow.IsControl) + if (firstSwap) { Debug.WriteLine("--> Resetting drawable. <--"); - firstSwap = true; + firstSwap = false; SetDrawable(carbonWindow); Update(carbonWindow); } - + Agl.aglSwapBuffers(Handle.Handle); MyAGLReportError("aglSwapBuffers"); } - public override void MakeCurrent(IWindowInfo window) + public void MakeCurrent(IWindowInfo window) { if (Agl.aglSetCurrentContext(Handle.Handle) == false) MyAGLReportError("aglSetCurrentContext"); } - public override bool IsCurrent + public bool IsCurrent { get { return (Handle.Handle == Agl.aglGetCurrentContext()); } } - public override int SwapInterval + public int SwapInterval { - get { + get + { int swap_interval = 0; if (Agl.aglGetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, out swap_interval)) { @@ -372,6 +253,64 @@ namespace OpenTK.Platform.MacOS } } + public GraphicsMode Mode + { + get + { + return mode; + } + set + { + mode = value; + } + + } + + public void LoadAll() + { + dummyContext.LoadAll(); + } + + public bool IsDisposed + { + get + { + return disposed; + } + } + + public bool VSync + { + get + { + return SwapInterval != 0; + } + set + { + SwapInterval = value ? 1 : 0; + } + } + + public GraphicsMode GraphicsMode + { + get + { + return mode; + } + } + + public bool ErrorChecking + { + get + { + return error_checking; + } + set + { + error_checking = value; + } + } + #endregion #region IDisposable Members @@ -381,7 +320,7 @@ namespace OpenTK.Platform.MacOS Dispose(false); } - public override void Dispose() + public void Dispose() { Dispose(true); } @@ -390,13 +329,13 @@ 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. @@ -410,34 +349,50 @@ namespace OpenTK.Platform.MacOS 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())); + throw new Exception(Agl.ErrorString(Agl.GetError())); } - - IsDisposed = true; + + disposed = true; } #endregion #region IGraphicsContextInternal Members - public override IntPtr GetAddress(string function) + public IntPtr GetAddress(string function) { return NS.GetAddress(function); } - public override IntPtr GetAddress(IntPtr function) + public IntPtr GetAddress(IntPtr function) { return NS.GetAddress(function); } + public IGraphicsContext Implementation + { + get + { + return this; + } + } + + public ContextHandle Context + { + get + { + return Handle; + } + } + #endregion } } diff --git a/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs b/Source/GLControl/AglGraphicsMode.cs similarity index 73% rename from Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs rename to Source/GLControl/AglGraphicsMode.cs index 7f09155b..786df4a1 100644 --- a/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs +++ b/Source/GLControl/AglGraphicsMode.cs @@ -33,46 +33,23 @@ using OpenTK.Graphics; namespace OpenTK.Platform.MacOS { - using Carbon; - - class MacOSGraphicsMode : IGraphicsMode + class AglGraphicsMode { - readonly IntPtr Device; - - public MacOSGraphicsMode(IntPtr device) - { - Device = device; - } - - #region IGraphicsMode Members - public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, - int samples, ColorFormat accum, int buffers, bool stereo) + int samples, ColorFormat accum, int buffers, bool stereo, out IntPtr pixelformat) { - IntPtr pixelformat; do { pixelformat = SelectPixelFormat( - color, depth, stencil, samples, accum, buffers, stereo, - true, Device); - - Agl.AglError err = Agl.GetError(); - if (pixelformat == IntPtr.Zero || err == Agl.AglError.BadPixelFormat) - { - Debug.Print("Failed to create full screen pixel format."); - Debug.Print("Trying again to create a non-fullscreen pixel format."); - pixelformat = SelectPixelFormat( - color, depth, stencil, samples, accum, buffers, stereo, - false, IntPtr.Zero); - } + color, depth, stencil, samples, accum, buffers, stereo); if (pixelformat == IntPtr.Zero) { - if (!Utilities.RelaxGraphicsMode( + if (!RelaxGraphicsMode( ref color, ref depth, ref stencil, ref samples, ref accum, ref buffers, ref stereo)) { - throw new GraphicsModeException("Requested GraphicsMode not available."); + throw new GraphicsModeException("Requested GraphicsMode not available, error: " + Agl.GetError()); } } } @@ -81,10 +58,76 @@ namespace OpenTK.Platform.MacOS return GetGraphicsModeFromPixelFormat(pixelformat); } - #endregion - #region Internal Members + static bool RelaxGraphicsMode(ref ColorFormat color, ref int depth, ref int stencil, ref int samples, ref ColorFormat accum, ref int buffers, ref bool stereo) + { + // Parameters are relaxed in order of importance. + // - Accumulator buffers are way outdated as a concept, + // so they go first. + // - Triple+ buffering is generally not supported by the + // core WGL/GLX/AGL/CGL/EGL specs, so we clamp + // to double-buffering as a second step. (If this doesn't help + // we will also fall back to undefined single/double buffering + // as a last resort). + // - AA samples are an easy way to increase compatibility + // so they go next. + // - Stereoscopic is only supported on very few GPUs + // (Quadro/FirePro series) so it goes next. + // - The rest of the parameters then follow. + + if (accum != 0) + { + accum = 0; + return true; + } + + if (buffers > 2) + { + buffers = 2; + return true; + } + + if (samples > 0) + { + samples = Math.Max(samples - 1, 0); + return true; + } + + if (stereo) + { + stereo = false; + return true; + } + + if (stencil != 0) + { + stencil = 0; + return true; + } + + if (depth != 0) + { + depth = 0; + return true; + } + + if (color != 24) + { + color = 24; + return true; + } + + if (buffers != 0) + { + buffers = 0; + return true; + } + + // no parameters left to relax, fail + return false; + } + GraphicsMode GetGraphicsModeFromPixelFormat(IntPtr pixelformat) { int r, g, b, a; @@ -104,12 +147,12 @@ namespace OpenTK.Platform.MacOS Agl.aglDescribePixelFormat(pixelformat, Agl.PixelFormatAttribute.AGL_DOUBLEBUFFER, out buffers); Agl.aglDescribePixelFormat(pixelformat, Agl.PixelFormatAttribute.AGL_STEREO, out stereo); - return new GraphicsMode(pixelformat, new ColorFormat(r, g, b, a), + return new GraphicsMode(new ColorFormat(r, g, b, a), depth, stencil, samples, new ColorFormat(ar, ag, ab, aa), buffers + 1, stereo != 0); } IntPtr SelectPixelFormat(ColorFormat color, int depth, int stencil, int samples, - ColorFormat accum, int buffers, bool stereo, bool fullscreen, IntPtr device) + ColorFormat accum, int buffers, bool stereo) { List attribs = new List(); @@ -144,7 +187,7 @@ namespace OpenTK.Platform.MacOS attribs.Add((int)Agl.PixelFormatAttribute.AGL_DOUBLEBUFFER); } - if (stencil > 1) + if (stencil > 0) { attribs.Add((int)Agl.PixelFormatAttribute.AGL_STENCIL_SIZE); attribs.Add(stencil); @@ -175,23 +218,10 @@ namespace OpenTK.Platform.MacOS attribs.Add((int)Agl.PixelFormatAttribute.AGL_STEREO); } - if (fullscreen) - { - attribs.Add((int)Agl.PixelFormatAttribute.AGL_FULLSCREEN); - } - attribs.Add(0); attribs.Add(0); - IntPtr pixelformat = IntPtr.Zero; - if (device != IntPtr.Zero) - { - pixelformat = Agl.aglChoosePixelFormat(ref device, 0, attribs.ToArray()); - } - else - { - pixelformat = Agl.aglChoosePixelFormat(IntPtr.Zero, 0, attribs.ToArray()); - } + IntPtr pixelformat = Agl.aglChoosePixelFormat(IntPtr.Zero, 0, attribs.ToArray()); return pixelformat; } diff --git a/Source/GLControl/Carbon.cs b/Source/GLControl/Carbon.cs new file mode 100644 index 00000000..eaa6d44a --- /dev/null +++ b/Source/GLControl/Carbon.cs @@ -0,0 +1,160 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace OpenTK.Platform.MacOS.Carbon +{ + internal 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 + } + + [StructLayout(LayoutKind.Sequential)] + internal struct Rect + { + short top; + short left; + short bottom; + short right; + + internal Rect(int left, int top, int width, int height) + : this((short)left, (short)top, (short)width, (short)height) + { + } + + internal Rect(short _left, short _top, short _width, short _height) + { + top = _top; + left = _left; + bottom = (short)(_top + _height); + right = (short)(_left + _width); + } + + internal short X + { + get { return left; } + set + { + short width = Width; + left = value; + right = (short)(left + width); + } + } + + internal short Y + { + get { return top; } + set + { + short height = Height; + top = value; + bottom = (short)(top + height); + } + } + + internal short Width + { + get { return (short)(right - left); } + set { right = (short)(left + value); } + } + + internal short Height + { + get { return (short)(bottom - top); } + set { bottom = (short)(top + value); } + } + + public override string ToString() + { + return string.Format( + "Rect: [{0}, {1}, {2}, {3}]", X, Y, Width, Height); + } + + public Rectangle ToRectangle() + { + return new Rectangle(X, Y, Width, Height); + } + } + + class API + { + const string carbon = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon"; + + [DllImport(carbon)] + internal unsafe static extern OSStatus DMGetGDeviceByDisplayID( + IntPtr displayID, out IntPtr displayDevice, Boolean failToMain); + + [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 IntPtr GetControlOwner(IntPtr control); + + [DllImport(carbon)] + internal static extern IntPtr GetWindowPort(IntPtr windowRef); + } +} + diff --git a/Source/GLControl/CarbonGLControl.cs b/Source/GLControl/CarbonGLControl.cs index 40cebef5..34f385a7 100644 --- a/Source/GLControl/CarbonGLControl.cs +++ b/Source/GLControl/CarbonGLControl.cs @@ -32,6 +32,7 @@ using System.Windows.Forms; using OpenTK.Graphics; using OpenTK.Platform; +using OpenTK.Platform.MacOS; namespace OpenTK { @@ -46,7 +47,7 @@ namespace OpenTK this.mode = mode; this.control = owner; - window_info = Utilities.CreateMacOSCarbonWindowInfo(control.Handle, false, true, GetXOffset, GetYOffset); + window_info = Utilities.CreateMacOSCarbonWindowInfo(control.Handle, false, true); } private int GetXOffset() @@ -70,7 +71,8 @@ namespace OpenTK public IGraphicsContext CreateContext(int major, int minor, GraphicsContextFlags flags) { - return new GraphicsContext(mode, WindowInfo, major, minor, flags); + // AGL does not support OpenGL profiles + return new AglContext(mode, WindowInfo, GraphicsContext.CurrentContext, GetXOffset, GetYOffset); } // TODO: Fix this diff --git a/Source/GLControl/NS.cs b/Source/GLControl/NS.cs new file mode 100644 index 00000000..281561d3 --- /dev/null +++ b/Source/GLControl/NS.cs @@ -0,0 +1,113 @@ +#region License +// +// NS.cs +// +// Author: +// Stefanos A. +// +// Copyright (c) 2006-2013 Stefanos Apostolopoulos +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// + +#endregion + +using System; +using System.Runtime.InteropServices; + +namespace OpenTK.Platform.MacOS +{ + internal class NS + { + const string Library = "libdl.dylib"; + + [DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")] + static extern bool NSIsSymbolNameDefined(string s); + [DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")] + static extern bool NSIsSymbolNameDefined(IntPtr s); + [DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")] + static extern IntPtr NSLookupAndBindSymbol(string s); + [DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")] + static extern IntPtr NSLookupAndBindSymbol(IntPtr s); + [DllImport(Library, EntryPoint = "NSAddressOfSymbol")] + static extern IntPtr NSAddressOfSymbol(IntPtr symbol); + [DllImport(Library)] + private static extern IntPtr dlopen(String fileName, int flags); + [DllImport(Library)] + private static extern int dlclose(IntPtr handle); + [DllImport (Library)] + private static extern IntPtr dlsym (IntPtr handle, string symbol); + + public static IntPtr GetAddress(string function) + { + // Instead of allocating and combining strings in managed memory + // we do that directly in unmanaged memory. This way, we avoid + // 2 string allocations every time this function is called. + + // must add a '_' prefix and null-terminate the function name, + // hence we allocate +2 bytes + IntPtr ptr = Marshal.AllocHGlobal(function.Length + 2); + try + { + Marshal.WriteByte(ptr, (byte)'_'); + for (int i = 0; i < function.Length; i++) + { + Marshal.WriteByte(ptr, i + 1, (byte)function[i]); + } + Marshal.WriteByte(ptr, function.Length + 1, 0); // null-terminate + + IntPtr symbol = GetAddress(ptr); + return symbol; + } + finally + { + Marshal.FreeHGlobal(ptr); + } + } + + public static IntPtr GetAddress(IntPtr function) + { + IntPtr symbol = IntPtr.Zero; + if (NSIsSymbolNameDefined(function)) + { + symbol = NSLookupAndBindSymbol(function); + if (symbol != IntPtr.Zero) + symbol = NSAddressOfSymbol(symbol); + } + return symbol; + } + + public static IntPtr GetSymbol(IntPtr handle, string symbol) + { + return dlsym(handle, symbol); + } + + public static IntPtr LoadLibrary(string fileName) + { + const int RTLD_NOW = 2; + return dlopen(fileName, RTLD_NOW); + } + + public static void FreeLibrary(IntPtr handle) + { + dlclose(handle); + } + } +} + diff --git a/Source/GLControl/OpenTK.GLControl.csproj b/Source/GLControl/OpenTK.GLControl.csproj index 019beb04..b9753496 100644 --- a/Source/GLControl/OpenTK.GLControl.csproj +++ b/Source/GLControl/OpenTK.GLControl.csproj @@ -162,6 +162,22 @@ Code + + CarbonGLControl.cs + Code + + + CarbonGLControl.cs + Code + + + CarbonGLControl.cs + Code + + + + CarbonGLControl.cs + diff --git a/Source/OpenTK/OpenTK.csproj b/Source/OpenTK/OpenTK.csproj index 2726c493..57fb4a44 100644 --- a/Source/OpenTK/OpenTK.csproj +++ b/Source/OpenTK/OpenTK.csproj @@ -282,9 +282,6 @@ Code - - Code - Code @@ -294,42 +291,12 @@ Code - - Code - Code - - Code - Code - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - Code @@ -820,7 +787,25 @@ - + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + diff --git a/Source/OpenTK/Platform/MacOS/Application.cs b/Source/OpenTK/Platform/MacOS/Application.cs index 093d4369..a55f45b4 100644 --- a/Source/OpenTK/Platform/MacOS/Application.cs +++ b/Source/OpenTK/Platform/MacOS/Application.cs @@ -39,7 +39,6 @@ namespace OpenTK.Platform.MacOS.Carbon { static bool mInitialized = false; static IntPtr uppHandler; - static CarbonGLNative eventHandler; static int osMajor, osMinor, osBugfix; static Application() @@ -76,12 +75,6 @@ namespace OpenTK.Platform.MacOS.Carbon API.SetFrontProcess(ref psn); } - static internal CarbonGLNative WindowEventHandler - { - get { return eventHandler; } - set { eventHandler = value; } - } - static void ConnectEvents() { @@ -131,36 +124,16 @@ namespace OpenTK.Platform.MacOS.Carbon return OSStatus.EventNotHandled; } - 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); - } - - break; } return OSStatus.EventNotHandled; } - public static void Run(CarbonGLNative window) - { - window.Closed += MainWindowClosed; - window.Visible = true; - - API.RunApplicationEventLoop(); - - window.Closed -= MainWindowClosed; - } - static void MainWindowClosed(object sender, EventArgs e) { Debug.Print("Quitting application event loop."); diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs b/Source/OpenTK/Platform/MacOS/Carbon/CarbonAPI.cs similarity index 100% rename from Source/OpenTK/Platform/MacOS/CarbonBindings/CarbonAPI.cs rename to Source/OpenTK/Platform/MacOS/Carbon/CarbonAPI.cs diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/Cgl.cs b/Source/OpenTK/Platform/MacOS/Carbon/Cgl.cs similarity index 100% rename from Source/OpenTK/Platform/MacOS/CarbonBindings/Cgl.cs rename to Source/OpenTK/Platform/MacOS/Carbon/Cgl.cs diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs b/Source/OpenTK/Platform/MacOS/Carbon/CoreFoundation.cs similarity index 100% rename from Source/OpenTK/Platform/MacOS/CarbonBindings/CoreFoundation.cs rename to Source/OpenTK/Platform/MacOS/Carbon/CoreFoundation.cs diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs b/Source/OpenTK/Platform/MacOS/Carbon/MacOSKeys.cs similarity index 100% rename from Source/OpenTK/Platform/MacOS/CarbonBindings/MacOSKeys.cs rename to Source/OpenTK/Platform/MacOS/Carbon/MacOSKeys.cs diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs b/Source/OpenTK/Platform/MacOS/Carbon/QuartzDisplayServicesAPI.cs similarity index 100% rename from Source/OpenTK/Platform/MacOS/CarbonBindings/QuartzDisplayServicesAPI.cs rename to Source/OpenTK/Platform/MacOS/Carbon/QuartzDisplayServicesAPI.cs diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/SpeechChannel.cs b/Source/OpenTK/Platform/MacOS/Carbon/SpeechChannel.cs similarity index 100% rename from Source/OpenTK/Platform/MacOS/CarbonBindings/SpeechChannel.cs rename to Source/OpenTK/Platform/MacOS/Carbon/SpeechChannel.cs diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs deleted file mode 100644 index 12baf2c9..00000000 --- a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs +++ /dev/null @@ -1,1147 +0,0 @@ -#region License -// -// The Open Toolkit Library License -// -// Copyright (c) 2006 - 2010 the Open Toolkit library. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -#endregion - -// Created by Erik Ylvisaker on 3/17/08. - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Drawing; -using System.Text; -using OpenTK.Graphics; -using OpenTK.Input; - -namespace OpenTK.Platform.MacOS -{ - using Carbon; -#if ANDROID || IPHONE || MINIMAL - using Minimal; - using Graphics = OpenTK.Minimal.Graphics; -#else - using Graphics = System.Drawing.Graphics; -#endif - - class CarbonGLNative : INativeWindow - { - #region Fields - - CarbonWindowInfo window; - CarbonInput mInputDriver; - - static MacOSKeyMap Keymap = new MacOSKeyMap(); - - IntPtr uppHandler; - - string title = "OpenTK Window"; - Rectangle bounds, clientRectangle; - Rectangle windowedBounds; - bool mIsDisposed = false; - bool mExists = true; - DisplayDevice mDisplayDevice; - - WindowPositionMethod mPositionMethod = WindowPositionMethod.CenterOnMainScreen; - int mTitlebarHeight; - private WindowBorder windowBorder = WindowBorder.Resizable; - private WindowState windowState = WindowState.Normal; - - static Dictionary mWindows = - new Dictionary(new IntPtrEqualityComparer()); - - KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs((char)0); - OpenTK.Input.KeyboardKeyEventArgs mKeyDownArgs = new OpenTK.Input.KeyboardKeyEventArgs(); - OpenTK.Input.KeyboardKeyEventArgs mKeyUpArgs = new OpenTK.Input.KeyboardKeyEventArgs(); - - bool mMouseIn = false; - bool mIsActive = false; - - Icon mIcon; - - // Used to accumulate mouse motion when the cursor is hidden. - float mouse_rel_x; - float mouse_rel_y; - - #endregion - - #region AGL Device Hack - - static internal Dictionary WindowRefMap - { - get { return mWindows; } - } - internal DisplayDevice TargetDisplayDevice - { - get { return mDisplayDevice; } - } - - #endregion - - #region Constructors - - static CarbonGLNative() - { - Application.Initialize(); - } - - public CarbonGLNative(int x, int y, int width, int height, string title, - GraphicsMode mode, GameWindowFlags options, DisplayDevice device) - { - CreateNativeWindow(WindowClass.Document, - WindowAttributes.StandardDocument | WindowAttributes.StandardHandler | - WindowAttributes.InWindowMenu | WindowAttributes.LiveResize, - new Rect((short)x, (short)y, (short)width, (short)height)); - - mDisplayDevice = device; - } - - #endregion - - #region IDisposable - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (mIsDisposed) - return; - - Debug.Print("Disposing of CarbonGLNative window."); - - CursorVisible = true; - API.DisposeWindow(window.Handle); - mIsDisposed = true; - mExists = false; - - CG.SetLocalEventsSuppressionInterval(0.25); - - if (disposing) - { - mWindows.Remove(window.Handle); - - window.Dispose(); - window = null; - } - - DisposeUPP(); - - Disposed(this, EventArgs.Empty); - } - - ~CarbonGLNative() - { - Dispose(false); - } - - #endregion - - #region Private Members - - 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); - - SetLocation(r.X, r.Y); - SetSize(r.Width, r.Height); - - Debug.Unindent(); - Debug.Print("Created window."); - - mWindows.Add(windowRef, new WeakReference(this)); - - LoadSize(); - - Rect titleSize = API.GetWindowBounds(window.Handle, WindowRegionCode.TitleBarRegion); - mTitlebarHeight = titleSize.Height; - - Debug.Print("Titlebar size: {0}", titleSize); - - ConnectEvents(); - - System.Diagnostics.Debug.WriteLine("Attached window events."); - } - - 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.Window, WindowEventKind.WindowActivate), - new EventTypeSpec(EventClass.Window, WindowEventKind.WindowDeactivate), - - //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.Handle, uppHandler, eventTypes, - window.Handle, IntPtr.Zero); - - Application.WindowEventHandler = this; - } - - void Activate() - { - API.SelectWindow(window.Handle); - } - - void Show() - { - IntPtr parent = IntPtr.Zero; - - API.ShowWindow(window.Handle); - API.RepositionWindow(window.Handle, parent, WindowPositionMethod); - API.SelectWindow(window.Handle); - } - - void Hide() - { - API.HideWindow(window.Handle); - } - - internal void SetFullscreen(AglContext context) - { - windowedBounds = bounds; - - int width, height; - - context.SetFullScreen(window, out width, out height); - - Debug.Print("Prev Size: {0}, {1}", Width, Height); - clientRectangle.Size = new Size(width, height); - Debug.Print("New Size: {0}, {1}", Width, Height); - - // TODO: if we go full screen we need to make this use the device specified. - bounds = mDisplayDevice.Bounds; - - - windowState = WindowState.Fullscreen; - } - - internal void UnsetFullscreen(AglContext context) - { - context.UnsetFullScreen(window); - - Debug.Print("Telling Carbon to reset window state to " + windowState.ToString()); - SetCarbonWindowState(); - - SetSize((short)windowedBounds.Width, (short)windowedBounds.Height); - } - - bool IsDisposed - { - get { return mIsDisposed; } - } - - WindowPositionMethod WindowPositionMethod - { - get { return mPositionMethod; } - set { mPositionMethod = value; } - } - - internal OSStatus DispatchEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) - { - switch (evt.EventClass) - { - case EventClass.Window: - return ProcessWindowEvent(inCaller, inEvent, evt, userData); - - case EventClass.Mouse: - return ProcessMouseEvent(inCaller, inEvent, evt, userData); - - case EventClass.Keyboard: - return ProcessKeyboardEvent(inCaller, inEvent, evt, userData); - - default: - return OSStatus.EventNotHandled; - } - } - - protected static OSStatus EventHandler(IntPtr inCaller, IntPtr inEvent, IntPtr userData) - { - if (mWindows.ContainsKey(userData) == false) - { - // Bail out if the window passed in is not actually our window. - // I think this happens if using winforms with a GameWindow sometimes. - return OSStatus.EventNotHandled; - } - - WeakReference reference = mWindows[userData]; - if (reference.IsAlive == false) - { - // Bail out if the CarbonGLNative window has been garbage collected. - mWindows.Remove(userData); - return OSStatus.EventNotHandled; - } - - CarbonGLNative window = (CarbonGLNative)reference.Target; - if (window == null) - { - Debug.WriteLine("Window for event not found."); - return OSStatus.EventNotHandled; - } - - EventInfo evt = new EventInfo(inEvent); - return window.DispatchEvent(inCaller, inEvent, evt, userData); - } - - private OSStatus ProcessKeyboardEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) - { - System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Keyboard); - MacOSKeyCode code = (MacOSKeyCode)0; - char charCode = '\0'; - - switch (evt.KeyboardEventKind) - { - case KeyboardEventKind.RawKeyDown: - case KeyboardEventKind.RawKeyRepeat: - case KeyboardEventKind.RawKeyUp: - GetCharCodes(inEvent, out code, out charCode); - mKeyPressArgs.KeyChar = charCode; - break; - } - - Key key; - switch (evt.KeyboardEventKind) - { - case KeyboardEventKind.RawKeyRepeat: - if (InputDriver.Keyboard[0].KeyRepeat) - goto case KeyboardEventKind.RawKeyDown; - break; - - case KeyboardEventKind.RawKeyDown: - ProcessKeyDown(code); - return OSStatus.NoError; - - case KeyboardEventKind.RawKeyUp: - ProcessKeyUp(code); - return OSStatus.NoError; - - case KeyboardEventKind.RawKeyModifiersChanged: - ProcessModifierKey(inEvent); - return OSStatus.NoError; - } - - 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(); - OnClosing(cancel); - - if (cancel.Cancel) - return OSStatus.NoError; - else - return OSStatus.EventNotHandled; - - case WindowEventKind.WindowClosed: - mExists = false; - OnClosed(); - - return OSStatus.NoError; - - case WindowEventKind.WindowBoundsChanged: - int thisWidth = Width; - int thisHeight = Height; - int thisX = X; - int thisY = Y; - - LoadSize(); - - if (thisX != X || thisY != Y) - Move(this, EventArgs.Empty); - - if (thisWidth != Width || thisHeight != Height) - Resize(this, EventArgs.Empty); - - return OSStatus.EventNotHandled; - - case WindowEventKind.WindowActivate: - OnActivate(); - return OSStatus.EventNotHandled; - - case WindowEventKind.WindowDeactivate: - OnDeactivate(); - 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(); - HIPoint screenLoc = new HIPoint(); - - IntPtr thisEventWindow; - API.GetEventWindowRef(inEvent, out thisEventWindow); - - OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc); - if (this.windowState == WindowState.Fullscreen) - { - pt = screenLoc; - } - else if (CursorVisible) - { - err = API.GetEventWindowMouseLocation(inEvent, out pt); - pt.Y -= mTitlebarHeight; - } - else - { - err = API.GetEventMouseDelta(inEvent, out pt); - pt.X += mouse_rel_x; - pt.Y += mouse_rel_y; - pt = ConfineMouseToWindow(thisEventWindow, pt); - ResetMouseToWindowCenter(); - mouse_rel_x = pt.X; - mouse_rel_y = pt.Y; - } - - if (err != OSStatus.NoError && err != OSStatus.EventParameterNotFound) - { - // this error comes up from the application event handler. - throw new MacOSException(err); - } - - Point mousePosInClient = new Point((int)pt.X, (int)pt.Y); - CheckEnterLeaveEvents(thisEventWindow, mousePosInClient); - - switch (evt.MouseEventKind) - { - case MouseEventKind.MouseDown: - case MouseEventKind.MouseUp: - button = API.GetEventMouseButton(inEvent); - bool pressed = evt.MouseEventKind == MouseEventKind.MouseDown; - - switch (button) - { - case MouseButton.Primary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = pressed; - break; - - case MouseButton.Secondary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = pressed; - break; - - case MouseButton.Tertiary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = pressed; - break; - } - return OSStatus.NoError; - - case MouseEventKind.WheelMoved: // older, integer resolution only - { - // this is really an int, we use a float to avoid clipping the wheel value - float delta = API.GetEventMouseWheelDelta (inEvent); - InputDriver.Mouse[0].WheelPrecise += delta; - } - return OSStatus.NoError; - - case MouseEventKind.WheelScroll: // newer, more precise X and Y scroll - { - API.ScrollDelta delta = API.GetEventWheelScroll(inEvent); - InputDriver.Mouse[0].WheelPrecise += delta.deltaY; - } - return OSStatus.NoError; - - case MouseEventKind.MouseMoved: - case MouseEventKind.MouseDragged: - if (this.windowState == WindowState.Fullscreen) - { - if (mousePosInClient.X != InputDriver.Mouse[0].X || mousePosInClient.Y != InputDriver.Mouse[0].Y) - { - InputDriver.Mouse[0].Position = mousePosInClient; - } - } - else - { - // ignore clicks in the title bar - if (pt.Y < 0) - return OSStatus.EventNotHandled; - - if (mousePosInClient.X != InputDriver.Mouse[0].X || mousePosInClient.Y != InputDriver.Mouse[0].Y) - { - InputDriver.Mouse[0].Position = mousePosInClient; - } - } - return OSStatus.EventNotHandled; - - default: - Debug.Print("{0}", evt); - return OSStatus.EventNotHandled; - } - } - - void ResetMouseToWindowCenter() - { - OpenTK.Input.Mouse.SetPosition( - (Bounds.Left + Bounds.Right) / 2, - (Bounds.Top + Bounds.Bottom) / 2); - } - - private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt) - { - if (window == null) - return; - - bool thisIn = eventWindowRef == window.Handle; - - if (pt.Y < 0) - thisIn = false; - - if (thisIn != mMouseIn) - { - mMouseIn = thisIn; - - if (mMouseIn) - OnMouseEnter(); - else - OnMouseLeave(); - } - } - - // Point in client (window) coordinates - private HIPoint ConfineMouseToWindow(IntPtr window, HIPoint client) - { - if (client.X < 0) - client.X = 0; - if (client.X >= Width) - client.X = Width - 1; - if (client.Y < 0) - client.Y = 0; - if (client.Y >= Height) - client.Y = Height - 1; - - return client; - } - - private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode) - { - code = API.GetEventKeyboardKeyCode(inEvent); - charCode = API.GetEventKeyboardChar(inEvent); - } - - void ProcessKeyDown(MacOSKeyCode code) - { - Key key; - Keymap.TryGetValue(code, out key); - - // Legacy keyboard API - KeyboardDevice keyboard = InputDriver.Keyboard[0]; - keyboard.SetKey(key, (uint)code, true); - - // Raise KeyDown for new keyboard API - mKeyDownArgs.Key = key; - mKeyDownArgs.Modifiers = keyboard.GetModifiers(); - - KeyDown(this, mKeyDownArgs); - - // Raise KeyPress for new keyboard API - if (!Char.IsControl(mKeyPressArgs.KeyChar)) - { - OnKeyPress(mKeyPressArgs); - } - } - - void ProcessKeyUp(MacOSKeyCode code) - { - Key key; - Keymap.TryGetValue(code, out key); - - // Legacy keyboard API - KeyboardDevice keyboard = InputDriver.Keyboard[0]; - keyboard.SetKey(key, (uint)code, false); - - // Raise KeyUp for new keyboard API - mKeyUpArgs.Key = key; - mKeyDownArgs.Modifiers = keyboard.GetModifiers(); - - KeyUp(this, mKeyUpArgs); - } - - void ProcessKey(MacOSKeyCode code, bool pressed) - { - if (pressed) - { - ProcessKeyDown(code); - } - else - { - ProcessKeyUp(code); - } - } - - 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; - - Input.KeyboardDevice keyboard = InputDriver.Keyboard[0]; - - if (keyboard[OpenTK.Input.Key.AltLeft] ^ option) - { - ProcessKey(MacOSKeyCode.OptionAlt, option); - } - - if (keyboard[OpenTK.Input.Key.ShiftLeft] ^ shift) - { - ProcessKey(MacOSKeyCode.Shift, shift); - } - - if (keyboard[OpenTK.Input.Key.WinLeft] ^ command) - { - ProcessKey(MacOSKeyCode.Command, command); - } - - if (keyboard[OpenTK.Input.Key.ControlLeft] ^ control) - { - ProcessKey(MacOSKeyCode.Control, control); - } - - if (keyboard[OpenTK.Input.Key.CapsLock] ^ caps) - { - ProcessKey(MacOSKeyCode.CapsLock, caps); - } - } - - Rect GetClientSize() - { - Rect retval = API.GetWindowBounds(window.Handle, WindowRegionCode.ContentRegion); - return retval; - } - - void SetClientSize(short width, short height) - { - if (WindowState == WindowState.Fullscreen) - return; - - Rect new_bounds = new Rect(Bounds.X, Bounds.Y, width, height); - API.SetWindowBounds(window.Handle, WindowRegionCode.ContentRegion, ref new_bounds); - LoadSize(); - } - - void SetLocation(short x, short y) - { - if (windowState == WindowState.Fullscreen) - return; - - Rect new_bounds = new Rect(x, y, Bounds.Width, Bounds.Height); - API.SetWindowBounds(window.Handle, WindowRegionCode.StructureRegion, ref new_bounds); - LoadSize(); - } - - void SetSize(short width, short height) - { - if (WindowState == WindowState.Fullscreen) - return; - - Rect new_bounds = new Rect(Bounds.X, Bounds.Y, width, height); - API.SetWindowBounds(window.Handle, WindowRegionCode.StructureRegion, ref new_bounds); - LoadSize(); - } - - private void LoadSize() - { - if (WindowState == WindowState.Fullscreen) - return; - - Rect r = API.GetWindowBounds(window.Handle, WindowRegionCode.StructureRegion); - bounds = new Rectangle(r.X, r.Y, r.Width, r.Height); - - r = API.GetWindowBounds(window.Handle, WindowRegionCode.ContentRegion); - clientRectangle = new Rectangle(0, 0, r.Width, r.Height); - } - - #endregion - - #region INativeWindow Members - - public void ProcessEvents() - { - Application.ProcessEvents(); - } - - public Point PointToClient(Point point) - { - Rect r = Carbon.API.GetWindowBounds(window.Handle, WindowRegionCode.ContentRegion); - return new Point(point.X - r.X, point.Y - r.Y); - } - - public Point PointToScreen(Point point) - { - Rect r = Carbon.API.GetWindowBounds(window.Handle, WindowRegionCode.ContentRegion); - return new Point(point.X + r.X, point.Y + r.Y); - } - - public bool Exists - { - get { return mExists; } - } - - public IWindowInfo WindowInfo - { - get { return window; } - } - - public bool IsIdle - { - get { return true; } - } - - public OpenTK.Input.IInputDriver InputDriver - { - get { return mInputDriver; } - } - - public Icon Icon - { - get { return mIcon; } - set - { - if (value != Icon) - { - SetIcon(value); - mIcon = value; - IconChanged(this, EventArgs.Empty); - } - } - } - - private void SetIcon(Icon icon) - { - // The code for this function was adapted from Mono's - // XplatUICarbon implementation, written by Geoff Norton - // http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUICarbon.cs?view=markup&pathrev=136932 - if (icon == null) - { - API.RestoreApplicationDockTileImage(); - } - - else - { - Bitmap bitmap; - int size; - IntPtr[] data; - int index; - - bitmap = new Bitmap(128, 128); - using (Graphics g = Graphics.FromImage(bitmap)) - { - g.DrawImage(icon.ToBitmap(), 0, 0, 128, 128); - } - index = 0; - size = bitmap.Width * bitmap.Height; - data = new IntPtr[size]; - - for (int y = 0; y < bitmap.Height; y++) - { - for (int x = 0; x < bitmap.Width; x++) - { - int pixel = bitmap.GetPixel(x, y).ToArgb(); - if (BitConverter.IsLittleEndian) - { - byte a = (byte)((pixel >> 24) & 0xFF); - byte r = (byte)((pixel >> 16) & 0xFF); - byte g = (byte)((pixel >> 8) & 0xFF); - byte b = (byte)(pixel & 0xFF); - data[index++] = (IntPtr)(a + (r << 8) + (g << 16) + (b << 24)); - } - - else - { - data[index++] = (IntPtr)pixel; - } - } - } - - IntPtr provider = API.CGDataProviderCreateWithData(IntPtr.Zero, data, size * 4, IntPtr.Zero); - IntPtr image = API.CGImageCreate(128, 128, 8, 32, 4 * 128, API.CGColorSpaceCreateDeviceRGB(), 4, provider, IntPtr.Zero, 0, - 0); - API.SetApplicationDockTileImage(image); - } - } - - public string Title - { - get { return title; } - set - { - if (value != Title) - { - API.SetWindowTitle(window.Handle, value); - title = value; - TitleChanged(this, EventArgs.Empty); - } - } - } - - public bool Visible - { - get { return API.IsWindowVisible(window.Handle); } - set - { - if (value != Visible) - { - if (value) - Show(); - else - Hide(); - - VisibleChanged(this, EventArgs.Empty); - } - } - } - - public bool Focused - { - get { return this.mIsActive; } - } - - public Rectangle Bounds - { - - get { return bounds; } - set - { - Location = value.Location; - Size = value.Size; - } - } - - public Point Location - { - get { return Bounds.Location; } - set { SetLocation((short)value.X, (short)value.Y); } - } - - public Size Size - { - get { return bounds.Size; } - set { SetSize((short)value.Width, (short)value.Height); } - } - - public int Width - { - get { return ClientRectangle.Width; } - set { SetClientSize((short)value, (short)Height); } - } - - public int Height - { - get { return ClientRectangle.Height; } - set { SetClientSize((short)Width, (short)value); } - } - - public int X - { - get { return Bounds.X; } - set { Location = new Point(value, Y); } - } - - public int Y - { - get { return Bounds.Y; } - set { Location = new Point(X, value); } - } - - public Rectangle ClientRectangle - { - get { return clientRectangle; } -// just set the size, and ignore the location value. -// this is the behavior of the Windows WinGLNative. - set { ClientSize = value.Size; } - } - - public Size ClientSize - { - get { return clientRectangle.Size; } - set - { - API.SizeWindow(window.Handle, (short)value.Width, (short)value.Height, true); - LoadSize(); - Resize(this, EventArgs.Empty); - } - } - - public bool CursorVisible - { - get { return CG.CursorIsVisible(); } - set - { - if (value) - { - CG.DisplayShowCursor(IntPtr.Zero); - CG.AssociateMouseAndMouseCursorPosition(true); - } - else - { - CG.DisplayHideCursor(IntPtr.Zero); - ResetMouseToWindowCenter(); - CG.AssociateMouseAndMouseCursorPosition(false); - } - } - } - - public void Close() - { - CancelEventArgs e = new CancelEventArgs(); - OnClosing(e); - - if (e.Cancel) - return; - - OnClosed(); - } - - public WindowState WindowState - { - get - { - if (windowState == WindowState.Fullscreen) - return WindowState.Fullscreen; - - if (Carbon.API.IsWindowCollapsed(window.Handle)) - return WindowState.Minimized; - - if (Carbon.API.IsWindowInStandardState(window.Handle)) - { - return WindowState.Maximized; - } - - return WindowState.Normal; - } - set - { - if (value == WindowState) - return; - - Debug.Print("Switching window state from {0} to {1}", WindowState, value); - WindowState oldState = WindowState; - - windowState = value; - - if (oldState == WindowState.Fullscreen) - { - window.GoWindowedHack = true; - - // when returning from full screen, wait until the context is updated - // to actually do the work. - return; - } - - if (oldState == WindowState.Minimized) - { - API.CollapseWindow(window.Handle, false); - } - - SetCarbonWindowState(); - } - } - - private void SetCarbonWindowState() - { - CarbonPoint idealSize; - - switch (windowState) - { - case WindowState.Fullscreen: - window.GoFullScreenHack = true; - - break; - - case WindowState.Maximized: - // hack because mac os has no concept of maximized. Instead windows are "zoomed" - // meaning they are maximized up to their reported ideal size. So we report a - // large ideal size. - idealSize = new CarbonPoint(9000, 9000); - API.ZoomWindowIdeal(window.Handle, WindowPartCode.inZoomOut, ref idealSize); - break; - - case WindowState.Normal: - if (WindowState == WindowState.Maximized) - { - idealSize = new CarbonPoint(); - API.ZoomWindowIdeal(window.Handle, WindowPartCode.inZoomIn, ref idealSize); - } - - break; - - case WindowState.Minimized: - API.CollapseWindow(window.Handle, true); - - break; - } - - - WindowStateChanged(this, EventArgs.Empty); - LoadSize(); - Resize(this, EventArgs.Empty); - } - - public WindowBorder WindowBorder - { - get { return windowBorder; } - set - { - if (windowBorder == value) - return; - - windowBorder = value; - - if (windowBorder == WindowBorder.Resizable) - { - API.ChangeWindowAttributes(window.Handle, WindowAttributes.Resizable | WindowAttributes.FullZoom, WindowAttributes.NoAttributes); - } - - else if (windowBorder == WindowBorder.Fixed) - { - API.ChangeWindowAttributes(window.Handle, WindowAttributes.NoAttributes, WindowAttributes.Resizable | WindowAttributes.FullZoom); - } - - WindowBorderChanged(this, EventArgs.Empty); - } - } - - #region --- Event wrappers --- - - private void OnKeyPress(KeyPressEventArgs keyPressArgs) - { - KeyPress(this, keyPressArgs); - } - - - private void OnWindowStateChanged() - { - WindowStateChanged(this, EventArgs.Empty); - } - - protected virtual void OnClosing(CancelEventArgs e) - { - Closing(this, e); - } - - protected virtual void OnClosed() - { - Closed(this, EventArgs.Empty); - } - - - private void OnMouseLeave() - { - MouseLeave(this, EventArgs.Empty); - } - - private void OnMouseEnter() - { - MouseEnter(this, EventArgs.Empty); - } - - private void OnActivate() - { - mIsActive = true; - FocusedChanged(this, EventArgs.Empty); - } - private void OnDeactivate() - { - mIsActive = false; - FocusedChanged(this, EventArgs.Empty); - } - - #endregion - - public event EventHandler Move = delegate { }; - public event EventHandler Resize = delegate { }; - public event EventHandler Closing = delegate { }; - public event EventHandler Closed = delegate { }; - public event EventHandler Disposed = delegate { }; - public event EventHandler IconChanged = delegate { }; - public event EventHandler TitleChanged = delegate { }; - public event EventHandler VisibleChanged = delegate { }; - public event EventHandler FocusedChanged = delegate { }; - public event EventHandler WindowBorderChanged = delegate { }; - public event EventHandler WindowStateChanged = delegate { }; - public event EventHandler KeyDown = delegate { }; - public event EventHandler KeyPress = delegate { }; - public event EventHandler KeyUp = delegate { }; - public event EventHandler MouseEnter = delegate { }; - public event EventHandler MouseLeave = delegate { }; - - #endregion - } -} diff --git a/Source/OpenTK/Platform/MacOS/CarbonInput.cs b/Source/OpenTK/Platform/MacOS/CarbonInput.cs deleted file mode 100644 index 640b99b8..00000000 --- a/Source/OpenTK/Platform/MacOS/CarbonInput.cs +++ /dev/null @@ -1,122 +0,0 @@ -#region License -// -// The Open Toolkit Library License -// -// Copyright (c) 2006 - 2010 the Open Toolkit library. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -#endregion - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; - -namespace OpenTK.Platform.MacOS -{ - using Input; - - class CarbonInput : IInputDriver, IInputDriver2 - { - List dummy_keyboard_list = new List(1); - List dummy_mice_list = new List(1); - List dummy_joystick_list = new List(1); - - internal CarbonInput() - { - dummy_mice_list.Add(new MouseDevice()); - dummy_keyboard_list.Add(new KeyboardDevice()); - dummy_joystick_list.Add(new JoystickDevice(0, 0, 0)); - } - - #region IInputDriver Members - - public void Poll() - { - } - - #endregion - - #region IKeyboardDriver Members - - public IList Keyboard - { - get { return dummy_keyboard_list; } - } - - #endregion - - #region IMouseDriver Members - - public IList Mouse - { - get { return dummy_mice_list; } - } - - #endregion - - #region IJoystickDriver Members - - public IList Joysticks - { - get { return dummy_joystick_list; } - } - - #endregion - - #region IDisposable Members - - public void Dispose() - { - } - - #endregion - - public IMouseDriver2 MouseDriver - { - get - { - throw new NotImplementedException(); - } - } - - public IKeyboardDriver2 KeyboardDriver - { - get - { - throw new NotImplementedException(); - } - } - - public IGamePadDriver GamePadDriver - { - get - { - throw new NotImplementedException(); - } - } - - public IJoystickDriver2 JoystickDriver - { - get { throw new NotImplementedException(); } - } - } -} diff --git a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs index 687857b2..a4c0b961 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs @@ -32,13 +32,6 @@ using System.Text; namespace OpenTK.Platform.MacOS { - /// - /// This delegate represents any method that takes no arguments and returns an int. - /// I would have used Func but that requires .NET 4 - /// - /// The int value that your method returns - public delegate int GetInt(); - /// \internal /// /// Describes a Carbon window. @@ -48,7 +41,7 @@ namespace OpenTK.Platform.MacOS IntPtr windowRef; bool ownHandle = false; bool disposed = false; - bool isControl = false; + bool isControl = true; bool goFullScreenHack = false; bool goWindowedHack = false; diff --git a/Source/OpenTK/Platform/MacOS/MacOSException.cs b/Source/OpenTK/Platform/MacOS/MacOSException.cs index 47489398..edc30fdb 100644 --- a/Source/OpenTK/Platform/MacOS/MacOSException.cs +++ b/Source/OpenTK/Platform/MacOS/MacOSException.cs @@ -47,7 +47,7 @@ namespace OpenTK.Platform.MacOS { this.errorCode = errorCode; } - internal MacOSException(Agl.AglError errorCode, string message) + internal MacOSException(int errorCode, string message) : base(message) { this.errorCode = (OSStatus)errorCode; diff --git a/Source/OpenTK/Platform/Utilities.cs b/Source/OpenTK/Platform/Utilities.cs index 66d2593e..8e4c78e4 100644 --- a/Source/OpenTK/Platform/Utilities.cs +++ b/Source/OpenTK/Platform/Utilities.cs @@ -18,6 +18,16 @@ using OpenTK.Graphics; namespace OpenTK.Platform { + namespace MacOS + { + /// + /// This delegate represents any method that takes no arguments and returns an int. + /// I would have used Func but that requires .NET 4 + /// + /// The int value that your method returns + public delegate int GetInt(); + } + /// /// Provides cross-platform utilities to help interact with the underlying platform. ///