diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs index 50ab9144..341d8fe9 100644 --- a/Source/OpenTK/Platform/MacOS/AglContext.cs +++ b/Source/OpenTK/Platform/MacOS/AglContext.cs @@ -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 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, CarbonWindowInfo carbonWindow, IntPtr shareContextRef, bool fullscreen) { - List aglAttributes = new List(); - + List aglAttributes = new List(); + 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 } } diff --git a/Source/OpenTK/Platform/MacOS/Application.cs b/Source/OpenTK/Platform/MacOS/Application.cs index 5c649787..a4d83b54 100644 --- a/Source/OpenTK/Platform/MacOS/Application.cs +++ b/Source/OpenTK/Platform/MacOS/Application.cs @@ -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(); } diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs index a656a430..57d7b13d 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs @@ -50,10 +50,10 @@ namespace OpenTK.Platform.MacOS string title = "OpenTK Window"; Rectangle bounds, clientRectangle; - Rectangle windowedBounds; + Rectangle windowedBounds; bool mIsDisposed = false; - bool mExists = true; - DisplayDevice mDisplayDevice; + bool mExists = true; + DisplayDevice mDisplayDevice; WindowAttributes mWindowAttrib; WindowClass mWindowClass; @@ -64,36 +64,38 @@ namespace OpenTK.Platform.MacOS static Dictionary mWindows = new Dictionary(); - KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs((char)0); + KeyPressEventArgs mKeyPressArgs = new KeyPressEventArgs((char)0); - bool mMouseIn = false; - bool mIsActive = false; + bool mMouseIn = false; + bool mIsActive = false; - Icon mIcon; + Icon mIcon; #endregion - #region AGL Device Hack + #region AGL Device Hack - static internal Dictionary WindowRefMap { get { return mWindows; } } - internal DisplayDevice TargetDisplayDevice { get { return mDisplayDevice; } } + static internal Dictionary WindowRefMap + { + get { return mWindows; } + } + internal DisplayDevice TargetDisplayDevice + { + get { return mDisplayDevice; } + } - #endregion + #endregion - #region Constructors + #region Constructors - static CarbonGLNative() + static CarbonGLNative() { Application.Initialize(); } - CarbonGLNative() - : this(WindowClass.Document, - WindowAttributes.StandardDocument | - WindowAttributes.StandardHandler | - WindowAttributes.InWindowMenu | - WindowAttributes.LiveResize) - { } + CarbonGLNative() : this(WindowClass.Document, WindowAttributes.StandardDocument | WindowAttributes.StandardHandler | WindowAttributes.InWindowMenu | WindowAttributes.LiveResize) + { + } CarbonGLNative(WindowClass @class, WindowAttributes attrib) @@ -104,12 +106,9 @@ namespace OpenTK.Platform.MacOS 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; + CreateNativeWindow(WindowClass.Document, WindowAttributes.StandardDocument | WindowAttributes.StandardHandler | WindowAttributes.InWindowMenu | WindowAttributes.LiveResize, new Rect((short)x, (short)y, (short)width, (short)height)); + + mDisplayDevice = device; } #endregion @@ -126,24 +125,24 @@ namespace OpenTK.Platform.MacOS { if (mIsDisposed) return; - + Debug.Print("Disposing of CarbonGLNative window."); - - API.DisposeWindow(window.WindowRef); - + + API.DisposeWindow(window.WindowRef); + mIsDisposed = true; - mExists = false; - + mExists = false; + if (disposing) { mWindows.Remove(window.WindowRef); - + window.Dispose(); window = null; } - + DisposeUPP(); - + Disposed(this, EventArgs.Empty); } @@ -163,7 +162,7 @@ namespace OpenTK.Platform.MacOS //API.RemoveEventHandler(uppHandler); //API.DisposeEventHandlerUPP(uppHandler); } - + uppHandler = IntPtr.Zero; } @@ -171,44 +170,37 @@ namespace OpenTK.Platform.MacOS { 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.WindowRef, WindowRegionCode.TitleBarRegion); mTitlebarHeight = titleSize.Height; - + Debug.Print("Titlebar size: {0}", titleSize); - + ConnectEvents(); - + System.Diagnostics.Debug.Print("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), @@ -216,18 +208,18 @@ namespace OpenTK.Platform.MacOS //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), - }; - + 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) }; + MacOSEventHandler handler = EventHandler; uppHandler = API.NewEventHandlerUPP(handler); - + API.InstallWindowEventHandler(window.WindowRef, uppHandler, eventTypes, window.WindowRef, IntPtr.Zero); - + Application.WindowEventHandler = this; } @@ -239,7 +231,7 @@ namespace OpenTK.Platform.MacOS void Show() { IntPtr parent = IntPtr.Zero; - + API.ShowWindow(window.WindowRef); API.RepositionWindow(window.WindowRef, parent, WindowPositionMethod); API.SelectWindow(window.WindowRef); @@ -253,29 +245,29 @@ namespace OpenTK.Platform.MacOS 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; + 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(); - + + Debug.Print("Telling Carbon to reset window state to " + windowState.ToString()); + SetCarbonWindowState(); + SetSize((short)windowedBounds.Width, (short)windowedBounds.Height); } @@ -294,17 +286,17 @@ namespace OpenTK.Platform.MacOS { 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; + 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; } } @@ -314,40 +306,40 @@ namespace OpenTK.Platform.MacOS // I think this happens if using winforms with a GameWindow sometimes. if (mWindows.ContainsKey(userData) == false) return OSStatus.EventNotHandled; - + WeakReference reference = mWindows[userData]; - + // bail out if the CarbonGLNative window has been garbage collected. if (reference.IsAlive == false) { mWindows.Remove(userData); return OSStatus.EventNotHandled; } - - CarbonGLNative window = (CarbonGLNative)reference.Target; - EventInfo evt = new EventInfo(inEvent); - + + CarbonGLNative window = (CarbonGLNative)reference.Target; + EventInfo evt = new EventInfo(inEvent); + //Debug.Print("Processing {0} event for {1}.", evt, window.window); - + if (window == null) { Debug.WriteLine("Window for event not found."); return OSStatus.EventNotHandled; } - + switch (evt.EventClass) { - case EventClass.Window: - return window.ProcessWindowEvent(inCaller, inEvent, evt, userData); - - case EventClass.Mouse: - return window.ProcessMouseEvent(inCaller, inEvent, evt, userData); - - case EventClass.Keyboard: - return window.ProcessKeyboardEvent(inCaller, inEvent, evt, userData); - - default: - return OSStatus.EventNotHandled; + case EventClass.Window: + return window.ProcessWindowEvent(inCaller, inEvent, evt, userData); + + case EventClass.Mouse: + return window.ProcessMouseEvent(inCaller, inEvent, evt, userData); + + case EventClass.Keyboard: + return window.ProcessKeyboardEvent(inCaller, inEvent, evt, userData); + default: + + return OSStatus.EventNotHandled; } } @@ -356,95 +348,95 @@ namespace OpenTK.Platform.MacOS System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Keyboard); MacOSKeyCode code = (MacOSKeyCode)0; char charCode = '\0'; - - //Debug.Print("Processing keyboard event {0}", evt.KeyboardEventKind); - - switch (evt.KeyboardEventKind) - { - case KeyboardEventKind.RawKeyDown: - case KeyboardEventKind.RawKeyRepeat: - case KeyboardEventKind.RawKeyUp: - GetCharCodes(inEvent, out code, out charCode); - mKeyPressArgs.KeyChar = charCode; - break; - } - + + //Debug.Print("Processing keyboard event {0}", evt.KeyboardEventKind); + switch (evt.KeyboardEventKind) { - case KeyboardEventKind.RawKeyRepeat: - InputDriver.Keyboard[0].KeyRepeat = true; - goto case KeyboardEventKind.RawKeyDown; - - case KeyboardEventKind.RawKeyDown: - OnKeyPress(mKeyPressArgs); - InputDriver.Keyboard[0][Keymap[code]] = true; - return OSStatus.NoError; - - case KeyboardEventKind.RawKeyUp: - InputDriver.Keyboard[0][Keymap[code]] = false; - - return OSStatus.NoError; - - case KeyboardEventKind.RawKeyModifiersChanged: - ProcessModifierKey(inEvent); - return OSStatus.NoError; - - default: - return OSStatus.EventNotHandled; + case KeyboardEventKind.RawKeyDown: + case KeyboardEventKind.RawKeyRepeat: + case KeyboardEventKind.RawKeyUp: + GetCharCodes(inEvent, out code, out charCode); + mKeyPressArgs.KeyChar = charCode; + break; } - - + + switch (evt.KeyboardEventKind) + { + case KeyboardEventKind.RawKeyRepeat: + InputDriver.Keyboard[0].KeyRepeat = true; + goto case KeyboardEventKind.RawKeyDown; + + case KeyboardEventKind.RawKeyDown: + OnKeyPress(mKeyPressArgs); + InputDriver.Keyboard[0][Keymap[code]] = true; + return OSStatus.NoError; + + case KeyboardEventKind.RawKeyUp: + InputDriver.Keyboard[0][Keymap[code]] = false; + + return OSStatus.NoError; + + case KeyboardEventKind.RawKeyModifiersChanged: + ProcessModifierKey(inEvent); + return OSStatus.NoError; + default: + + return OSStatus.EventNotHandled; + } + + } private OSStatus ProcessWindowEvent(IntPtr inCaller, IntPtr inEvent, EventInfo evt, IntPtr userData) { System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Window); - + switch (evt.WindowEventKind) { - case WindowEventKind.WindowClose: - CancelEventArgs cancel = new CancelEventArgs(); - OnClosing(cancel); - - if (cancel.Cancel) - return OSStatus.NoError; - else - return OSStatus.EventNotHandled; - - case WindowEventKind.WindowClosed: - mExists = false; - OnClosed(); - + case WindowEventKind.WindowClose: + CancelEventArgs cancel = new CancelEventArgs(); + OnClosing(cancel); + + if (cancel.Cancel) 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); - + 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) @@ -452,19 +444,20 @@ namespace OpenTK.Platform.MacOS System.Diagnostics.Debug.Assert(evt.EventClass == EventClass.Mouse); MouseButton button = MouseButton.Primary; HIPoint pt = new HIPoint(); - HIPoint screenLoc = new HIPoint(); - - OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc); - + HIPoint screenLoc = new HIPoint(); + + OSStatus err = API.GetEventMouseLocation(inEvent, out screenLoc); + if (this.windowState == WindowState.Fullscreen) { - pt = screenLoc; + pt = screenLoc; } + else { err = API.GetEventWindowMouseLocation(inEvent, out pt); } - + if (err != OSStatus.NoError) { // this error comes up from the application event handler. @@ -473,126 +466,128 @@ namespace OpenTK.Platform.MacOS throw new MacOSException(err); } } - - Point mousePosInClient = new Point((int)pt.X, (int)pt.Y); - if (this.windowState != WindowState.Fullscreen) - { - mousePosInClient.Y -= mTitlebarHeight; - } - - // check for enter/leave events - IntPtr thisEventWindow; - API.GetEventWindowRef(inEvent, out thisEventWindow); - CheckEnterLeaveEvents(thisEventWindow, mousePosInClient); - + + Point mousePosInClient = new Point((int)pt.X, (int)pt.Y); + if (this.windowState != WindowState.Fullscreen) + { + mousePosInClient.Y -= mTitlebarHeight; + } + + // check for enter/leave events + IntPtr thisEventWindow; + API.GetEventWindowRef(inEvent, out thisEventWindow); + CheckEnterLeaveEvents(thisEventWindow, mousePosInClient); + switch (evt.MouseEventKind) { - case MouseEventKind.MouseDown: - button = API.GetEventMouseButton(inEvent); + case MouseEventKind.MouseDown: + button = API.GetEventMouseButton(inEvent); + + switch (button) + { + case MouseButton.Primary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = true; + break; + + case MouseButton.Secondary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = true; + break; + + case MouseButton.Tertiary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = true; + break; + } - switch (button) + + + return OSStatus.NoError; + + case MouseEventKind.MouseUp: + button = API.GetEventMouseButton(inEvent); + + switch (button) + { + case MouseButton.Primary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = false; + break; + + case MouseButton.Secondary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = false; + break; + + case MouseButton.Tertiary: + InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = false; + break; + } + + + button = API.GetEventMouseButton(inEvent); + + return OSStatus.NoError; + + case MouseEventKind.WheelMoved: + + int delta = API.GetEventMouseWheelDelta(inEvent) / 3; + + InputDriver.Mouse[0].Wheel += delta; + + return OSStatus.NoError; + + case MouseEventKind.MouseMoved: + case MouseEventKind.MouseDragged: + + //Debug.Print("Mouse Location: {0}, {1}", pt.X, pt.Y); + + if (this.windowState == WindowState.Fullscreen) + { + if (mousePosInClient.X != InputDriver.Mouse[0].X || mousePosInClient.Y != InputDriver.Mouse[0].Y) { - case MouseButton.Primary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = true; - break; - - case MouseButton.Secondary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = true; - break; - - case MouseButton.Tertiary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = true; - break; + InputDriver.Mouse[0].Position = mousePosInClient; } + } - - return OSStatus.NoError; - - case MouseEventKind.MouseUp: - button = API.GetEventMouseButton(inEvent); - - switch (button) + 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) { - case MouseButton.Primary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Left] = false; - break; - - case MouseButton.Secondary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Right] = false; - break; - - case MouseButton.Tertiary: - InputDriver.Mouse[0][OpenTK.Input.MouseButton.Middle] = false; - break; + InputDriver.Mouse[0].Position = mousePosInClient; } + } - button = API.GetEventMouseButton(inEvent); - - return OSStatus.NoError; - - case MouseEventKind.WheelMoved: - - int delta = API.GetEventMouseWheelDelta(inEvent) / 3; - - InputDriver.Mouse[0].Wheel += delta; - - return OSStatus.NoError; - - case MouseEventKind.MouseMoved: - case MouseEventKind.MouseDragged: - - //Debug.Print("Mouse Location: {0}, {1}", pt.X, pt.Y); - - 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; + + return OSStatus.EventNotHandled; + default: + + Debug.Print("{0}", evt); + + return OSStatus.EventNotHandled; } } - private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt) - { - if (window == null) - return; - - bool thisIn = eventWindowRef == window.WindowRef; - - if (pt.Y < 0) - thisIn = false; - - if (thisIn != mMouseIn) - { - mMouseIn = thisIn; - - if (mMouseIn) - OnMouseEnter(); - else - OnMouseLeave(); - } - } + private void CheckEnterLeaveEvents(IntPtr eventWindowRef, Point pt) + { + if (window == null) + return; + + bool thisIn = eventWindowRef == window.WindowRef; + + if (pt.Y < 0) + thisIn = false; + + if (thisIn != mMouseIn) + { + mMouseIn = thisIn; + + if (mMouseIn) + OnMouseEnter(); + else + OnMouseLeave(); + } + } private static void GetCharCodes(IntPtr inEvent, out MacOSKeyCode code, out char charCode) { @@ -602,38 +597,38 @@ namespace OpenTK.Platform.MacOS private void ProcessModifierKey(IntPtr inEvent) { MacOSKeyModifiers modifiers = API.GetEventKeyModifiers(inEvent); - + bool caps = (modifiers & MacOSKeyModifiers.CapsLock) != 0 ? true : false; bool control = (modifiers & MacOSKeyModifiers.Control) != 0 ? true : false; bool command = (modifiers & MacOSKeyModifiers.Command) != 0 ? true : false; bool option = (modifiers & MacOSKeyModifiers.Option) != 0 ? true : false; bool shift = (modifiers & MacOSKeyModifiers.Shift) != 0 ? true : false; - + Debug.Print("Modifiers Changed: {0}", modifiers); - + Input.KeyboardDevice keyboard = InputDriver.Keyboard[0]; - + if (keyboard[OpenTK.Input.Key.AltLeft] ^ option) keyboard[OpenTK.Input.Key.AltLeft] = option; - + if (keyboard[OpenTK.Input.Key.ShiftLeft] ^ shift) keyboard[OpenTK.Input.Key.ShiftLeft] = shift; - + if (keyboard[OpenTK.Input.Key.WinLeft] ^ command) keyboard[OpenTK.Input.Key.WinLeft] = command; - + if (keyboard[OpenTK.Input.Key.ControlLeft] ^ control) keyboard[OpenTK.Input.Key.ControlLeft] = control; - + if (keyboard[OpenTK.Input.Key.CapsLock] ^ caps) keyboard[OpenTK.Input.Key.CapsLock] = caps; - + } Rect GetRegion() { Rect retval = API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); - + return retval; } @@ -641,7 +636,7 @@ namespace OpenTK.Platform.MacOS { if (windowState == WindowState.Fullscreen) return; - + API.MoveWindow(window.WindowRef, x, y, false); } @@ -649,42 +644,42 @@ namespace OpenTK.Platform.MacOS { if (WindowState == WindowState.Fullscreen) return; - - // The bounds of the window should be the size specified, but - // API.SizeWindow sets the content region size. So - // we reduce the size to get the correct bounds. - width -= (short)(bounds.Width - clientRectangle.Width); - height -= (short)(bounds.Height - clientRectangle.Height); + + // The bounds of the window should be the size specified, but + // API.SizeWindow sets the content region size. So + // we reduce the size to get the correct bounds. + width -= (short)(bounds.Width - clientRectangle.Width); + height -= (short)(bounds.Height - clientRectangle.Height); + + API.SizeWindow(window.WindowRef, width, height, true); + } + + void SetClientSize(short width, short height) + { + if (WindowState == WindowState.Fullscreen) + return; API.SizeWindow(window.WindowRef, width, height, true); } - void SetClientSize(short width, short height) - { - if (WindowState == WindowState.Fullscreen) - return; - - API.SizeWindow(window.WindowRef, width, height, true); - } - private void LoadSize() { if (WindowState == WindowState.Fullscreen) return; - - Rect r = API.GetWindowBounds(window.WindowRef, WindowRegionCode.StructureRegion); - bounds = new Rectangle(r.X, r.Y, r.Width, r.Height); - - r = API.GetWindowBounds(window.WindowRef, WindowRegionCode.GlobalPortRegion); - clientRectangle = new Rectangle(0, 0, r.Width, r.Height); + + Rect r = API.GetWindowBounds(window.WindowRef, WindowRegionCode.StructureRegion); + bounds = new Rectangle(r.X, r.Y, r.Width, r.Height); + + r = API.GetWindowBounds(window.WindowRef, WindowRegionCode.GlobalPortRegion); + clientRectangle = new Rectangle(0, 0, r.Width, r.Height); } #endregion - #region INativeWindow Members + #region INativeWindow Members - public void ProcessEvents() + public void ProcessEvents() { Application.ProcessEvents(); } @@ -693,15 +688,15 @@ namespace OpenTK.Platform.MacOS { Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); Debug.Print("Rect: {0}", r); - + return new Point(point.X - r.X, point.Y - r.Y); } public Point PointToScreen(Point point) { - Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); - Debug.Print("Rect: {0}", r); - - return new Point(point.X + r.X, point.Y + r.Y); + Rect r = Carbon.API.GetWindowBounds(window.WindowRef, WindowRegionCode.ContentRegion); + Debug.Print("Rect: {0}", r); + + return new Point(point.X + r.X, point.Y + r.Y); } public bool Exists @@ -721,10 +716,7 @@ namespace OpenTK.Platform.MacOS public OpenTK.Input.IInputDriver InputDriver { - get - { - return mInputDriver; - } + get { return mInputDriver; } } @@ -742,63 +734,63 @@ namespace OpenTK.Platform.MacOS } } - 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; + 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(); + } - bitmap = new Bitmap(128, 128); - using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap)) - { - g.DrawImage(icon.ToBitmap(), 0, 0, 128, 128); - } - index = 0; - size = bitmap.Width * bitmap.Height; - data = new IntPtr[size]; + else + { + Bitmap bitmap; + int size; + IntPtr[] data; + int index; + + bitmap = new Bitmap(128, 128); + using (System.Drawing.Graphics g = System.Drawing.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)); + } - 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); - } - } + 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; - } + get { return title; } set { if (value != Title) @@ -821,7 +813,7 @@ namespace OpenTK.Platform.MacOS Show(); else Hide(); - + VisibleChanged(this, EventArgs.Empty); } } @@ -829,16 +821,13 @@ namespace OpenTK.Platform.MacOS public bool Focused { - get { return this.mIsActive; } + get { return this.mIsActive; } } public Rectangle Bounds { - get - { - - return bounds; - } + + get { return bounds; } set { Location = value.Location; @@ -848,26 +837,14 @@ namespace OpenTK.Platform.MacOS public Point Location { - get - { - return Bounds.Location; - } - set - { - SetLocation((short)value.X, (short)value.Y); - } + 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); - } + get { return bounds.Size; } + set { SetSize((short)value.Width, (short)value.Height); } } public int Width @@ -884,51 +861,30 @@ namespace OpenTK.Platform.MacOS public int X { - get - { - return ClientRectangle.X; - } - set - { - Location = new Point(value, Y); - } + get { return ClientRectangle.X; } + set { Location = new Point(value, Y); } } public int Y { - get - { - return ClientRectangle.Y; - } - set - { - Location = new Point(X, value); - } + get { return ClientRectangle.Y; } + set { Location = new Point(X, value); } } public Rectangle ClientRectangle { - get - { - return clientRectangle; - } - set - { - // just set the size, and ignore the location value. - // this is the behavior of the Windows WinGLNative. - ClientSize = value.Size; - } + 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; - } + get { return clientRectangle.Size; } set { - API.SizeWindow(window.WindowRef, (short)value.Width, (short)value.Height, true); + API.SizeWindow(window.WindowRef, (short)value.Width, (short)value.Height, true); LoadSize(); Resize(this, EventArgs.Empty); } @@ -942,15 +898,15 @@ namespace OpenTK.Platform.MacOS public void Close() { - CancelEventArgs e = new CancelEventArgs(); - OnClosing(e); - - if (e.Cancel) - return; - - OnClosed(); - - Dispose(); + CancelEventArgs e = new CancelEventArgs(); + OnClosing(e); + + if (e.Cancel) + return; + + OnClosed(); + + Dispose(); } public WindowState WindowState @@ -959,158 +915,155 @@ namespace OpenTK.Platform.MacOS { if (windowState == WindowState.Fullscreen) return WindowState.Fullscreen; - + if (Carbon.API.IsWindowCollapsed(window.WindowRef)) return WindowState.Minimized; - + if (Carbon.API.IsWindowInStandardState(window.WindowRef)) { 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) + 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; + 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.WindowRef, false); } - - SetCarbonWindowState(); + + 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.WindowRef, WindowPartCode.inZoomOut, ref idealSize); - break; - - case WindowState.Normal: - if (WindowState == WindowState.Maximized) - { - idealSize = new CarbonPoint(); - API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomIn, ref idealSize); - } - break; - - case WindowState.Minimized: - API.CollapseWindow(window.WindowRef, true); - - break; - } - + 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.WindowRef, WindowPartCode.inZoomOut, ref idealSize); + break; + + case WindowState.Normal: + if (WindowState == WindowState.Maximized) + { + idealSize = new CarbonPoint(); + API.ZoomWindowIdeal(window.WindowRef, WindowPartCode.inZoomIn, ref idealSize); + } + break; + + case WindowState.Minimized: + API.CollapseWindow(window.WindowRef, true); + + break; + } + + WindowStateChanged(this, EventArgs.Empty); LoadSize(); Resize(this, EventArgs.Empty); - } + } - public WindowBorder WindowBorder - { - get - { - return windowBorder; - } - set - { - if (windowBorder == value) - return; + public WindowBorder WindowBorder + { + get { return windowBorder; } + set + { + if (windowBorder == value) + return; + + windowBorder = value; + + if (windowBorder == WindowBorder.Resizable) + { + API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.Resizable | WindowAttributes.FullZoom, WindowAttributes.NoAttributes); + } - windowBorder = value; + else if (windowBorder == WindowBorder.Fixed) + { + API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.NoAttributes, WindowAttributes.Resizable | WindowAttributes.FullZoom); + } + + WindowBorderChanged(this, EventArgs.Empty); + } + } - if (windowBorder == WindowBorder.Resizable) - { - API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.Resizable | WindowAttributes.FullZoom, - WindowAttributes.NoAttributes); - } - else if (windowBorder == WindowBorder.Fixed) - { - API.ChangeWindowAttributes(window.WindowRef, WindowAttributes.NoAttributes, - WindowAttributes.Resizable | WindowAttributes.FullZoom); - } + #region --- Event wrappers --- - WindowBorderChanged(this, EventArgs.Empty); - } - } - - #region --- Event wrappers --- - - private void OnKeyPress(KeyPressEventArgs keyPressArgs) - { - KeyPress(this, keyPressArgs); - } + private void OnKeyPress(KeyPressEventArgs keyPressArgs) + { + KeyPress(this, keyPressArgs); + } - private void OnWindowStateChanged() - { - WindowStateChanged(this, EventArgs.Empty); - } + private void OnWindowStateChanged() + { + WindowStateChanged(this, EventArgs.Empty); + } - protected virtual void OnClosing(CancelEventArgs e) - { - Closing(this, e); - } + protected virtual void OnClosing(CancelEventArgs e) + { + Closing(this, e); + } - protected virtual void OnClosed() - { - Closed(this, EventArgs.Empty); - } + protected virtual void OnClosed() + { + Closed(this, EventArgs.Empty); + } - private void OnMouseLeave() - { - MouseLeave(this, EventArgs.Empty); - } + private void OnMouseLeave() + { + MouseLeave(this, EventArgs.Empty); + } - private void OnMouseEnter() - { - MouseEnter(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); - } + private void OnActivate() + { + mIsActive = true; + FocusedChanged(this, EventArgs.Empty); + } + private void OnDeactivate() + { + mIsActive = false; + FocusedChanged(this, EventArgs.Empty); + } - #endregion + #endregion public event EventHandler Move = delegate { }; public event EventHandler Resize = delegate { }; @@ -1126,7 +1079,7 @@ namespace OpenTK.Platform.MacOS public event EventHandler KeyPress = 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 index 615c0899..654e8321 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonInput.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonInput.cs @@ -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(); + } } } } diff --git a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs index 7f3eabdf..cd594a49 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonWindowInfo.cs @@ -36,14 +36,14 @@ namespace OpenTK.Platform.MacOS /// /// Describes a Carbon window. /// - 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; } + } /// @@ -96,8 +96,7 @@ namespace OpenTK.Platform.MacOS /// A System.String that represents the current window. 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 } } diff --git a/Source/OpenTK/Platform/MacOS/EventInfo.cs b/Source/OpenTK/Platform/MacOS/EventInfo.cs index 87ea61dc..c5400001 100644 --- a/Source/OpenTK/Platform/MacOS/EventInfo.cs +++ b/Source/OpenTK/Platform/MacOS/EventInfo.cs @@ -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(); } } diff --git a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs index e16a58bc..c83163db 100644 --- a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs +++ b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs @@ -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 } } diff --git a/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs b/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs index ef3590ce..c49d3401 100644 --- a/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs +++ b/Source/OpenTK/Platform/MacOS/MacOSGraphicsMode.cs @@ -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 } } diff --git a/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs b/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs index a92f160f..e5ffc834 100644 --- a/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs +++ b/Source/OpenTK/Platform/MacOS/MacOSKeyMap.cs @@ -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); - + } } } diff --git a/Source/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs b/Source/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs index 3f3e65af..999b1d45 100644 --- a/Source/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs +++ b/Source/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs @@ -11,11 +11,13 @@ namespace OpenTK.Platform.MacOS { static object display_lock = new object(); - static Dictionary displayMap = - new Dictionary(); + static Dictionary displayMap = new Dictionary(); 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 opentk_dev_available_res = new List(); 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 storedModes = new Dictionary(); List displaysCaptured = new List(); - + 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 - - } + + } }