diff --git a/Source/OpenTK/Input/IInputDriver2.cs b/Source/OpenTK/Input/IInputDriver2.cs
index 1ff89748..7cd788aa 100644
--- a/Source/OpenTK/Input/IInputDriver2.cs
+++ b/Source/OpenTK/Input/IInputDriver2.cs
@@ -1,41 +1,41 @@
-#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.Text;
-
-namespace OpenTK.Input
-{
- // Defines the interface for a 2nd generation input driver.
- interface IInputDriver2
- {
- IMouseDriver2 MouseDriver { get; }
- IKeyboardDriver2 KeyboardDriver { get; }
- IGamePadDriver GamePadDriver { get; }
- }
-}
+#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.Text;
+
+namespace OpenTK.Input
+{
+ // Defines the interface for a 2nd generation input driver.
+ interface IInputDriver2 : IDisposable
+ {
+ IMouseDriver2 MouseDriver { get; }
+ IKeyboardDriver2 KeyboardDriver { get; }
+ IGamePadDriver GamePadDriver { get; }
+ }
+}
diff --git a/Source/OpenTK/Platform/Factory.cs b/Source/OpenTK/Platform/Factory.cs
index e2c4b0e9..2fe318db 100644
--- a/Source/OpenTK/Platform/Factory.cs
+++ b/Source/OpenTK/Platform/Factory.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Text;
namespace OpenTK.Platform
@@ -37,6 +38,7 @@ namespace OpenTK.Platform
{
#region Fields
+ bool disposed;
static IPlatformFactory default_implementation, embedded_implementation;
#endregion
@@ -133,7 +135,8 @@ namespace OpenTK.Platform
class UnsupportedPlatform : IPlatformFactory
{
#region Fields
-
+
+ bool disposed;
static readonly string error_string = "Please, refer to http://www.opentk.com for more information.";
#endregion
@@ -191,6 +194,72 @@ namespace OpenTK.Platform
}
#endregion
+
+ #region IDisposable Members
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ // nothing to do
+ }
+ else
+ {
+ Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~UnsupportedPlatform()
+ {
+ Dispose(false);
+ }
+
+ #endregion
+ }
+
+ #endregion
+
+ #region IDisposable Members
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ Default.Dispose();
+ if (Embedded != Default)
+ {
+ Embedded.Dispose();
+ }
+ }
+ else
+ {
+ Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~Factory()
+ {
+ Dispose(false);
}
#endregion
diff --git a/Source/OpenTK/Platform/IPlatformFactory.cs b/Source/OpenTK/Platform/IPlatformFactory.cs
index 4b968cc9..541c8710 100644
--- a/Source/OpenTK/Platform/IPlatformFactory.cs
+++ b/Source/OpenTK/Platform/IPlatformFactory.cs
@@ -33,7 +33,7 @@ using OpenTK.Graphics;
namespace OpenTK.Platform
{
- interface IPlatformFactory
+ interface IPlatformFactory : IDisposable
{
INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device);
diff --git a/Source/OpenTK/Platform/MacOS/Application.cs b/Source/OpenTK/Platform/MacOS/Application.cs
index a972f1c1..093d4369 100644
--- a/Source/OpenTK/Platform/MacOS/Application.cs
+++ b/Source/OpenTK/Platform/MacOS/Application.cs
@@ -120,28 +120,32 @@ namespace OpenTK.Platform.MacOS.Carbon
switch (evt.EventClass)
{
- case EventClass.Application:
- switch (evt.AppEventKind)
- {
- default:
- return OSStatus.EventNotHandled;
- }
+ case EventClass.Application:
+ switch (evt.AppEventKind)
+ {
+ case AppEventKind.AppQuit:
+ API.RemoveEventHandler(uppHandler);
+ return OSStatus.EventNotHandled;
+
+ default:
+ return OSStatus.EventNotHandled;
+ }
- case EventClass.AppleEvent:
+ case EventClass.AppleEvent:
// only event here is the apple event.
- Debug.Print("Processing apple event.");
- API.ProcessAppleEvent(inEvent);
- break;
+ 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;
diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
index 15a0b8d9..cfa5f16a 100644
--- a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
+++ b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs
@@ -175,8 +175,8 @@ namespace OpenTK.Platform.MacOS
{
if (uppHandler != IntPtr.Zero)
{
- //API.RemoveEventHandler(uppHandler);
- //API.DisposeEventHandlerUPP(uppHandler);
+ API.RemoveEventHandler(uppHandler);
+ API.DisposeEventHandlerUPP(uppHandler);
}
uppHandler = IntPtr.Zero;
@@ -925,8 +925,6 @@ namespace OpenTK.Platform.MacOS
return;
OnClosed();
-
- Dispose();
}
public WindowState WindowState
diff --git a/Source/OpenTK/Platform/MacOS/HIDInput.cs b/Source/OpenTK/Platform/MacOS/HIDInput.cs
index c040ff6d..8e3c6011 100755
--- a/Source/OpenTK/Platform/MacOS/HIDInput.cs
+++ b/Source/OpenTK/Platform/MacOS/HIDInput.cs
@@ -69,9 +69,11 @@ namespace OpenTK.Platform.MacOS
readonly CFString InputLoopMode = CF.RunLoopModeDefault;
readonly CFDictionary DeviceTypes = new CFDictionary();
- readonly NativeMethods.IOHIDDeviceCallback HandleDeviceAdded;
- readonly NativeMethods.IOHIDDeviceCallback HandleDeviceRemoved;
- readonly NativeMethods.IOHIDValueCallback HandleDeviceValueReceived;
+ NativeMethods.IOHIDDeviceCallback HandleDeviceAdded;
+ NativeMethods.IOHIDDeviceCallback HandleDeviceRemoved;
+ NativeMethods.IOHIDValueCallback HandleDeviceValueReceived;
+
+ bool disposed;
#endregion
@@ -164,6 +166,7 @@ namespace OpenTK.Platform.MacOS
// Thanks to Jase: http://www.opentk.com/node/2800
NativeMethods.IOHIDDeviceRegisterInputValueCallback(device,
HandleDeviceValueReceived, device);
+
NativeMethods.IOHIDDeviceScheduleWithRunLoop(device, RunLoop, InputLoopMode);
}
}
@@ -192,12 +195,19 @@ namespace OpenTK.Platform.MacOS
KeyboardDevices[device] = state;
}
- NativeMethods.IOHIDDeviceRegisterInputValueCallback(device, null, IntPtr.Zero);
+ NativeMethods.IOHIDDeviceRegisterInputValueCallback(device, IntPtr.Zero, IntPtr.Zero);
NativeMethods.IOHIDDeviceUnscheduleWithRunLoop(device, RunLoop, InputLoopMode);
}
void DeviceValueReceived(IntPtr context, IOReturn res, IntPtr sender, IOHIDValueRef val)
{
+ if (disposed)
+ {
+ Debug.Print("DeviceValueReceived({0}, {1}, {2}, {3}) called on disposed {4}",
+ context, res, sender, val, GetType());
+ return;
+ }
+
MouseState mouse;
KeyboardState keyboard;
if (MouseDevices.TryGetValue(context, out mouse))
@@ -383,6 +393,12 @@ namespace OpenTK.Platform.MacOS
IOHIDDeviceCallback inIOHIDDeviceCallback,
IntPtr inContext);
+ [DllImport(hid)]
+ public static extern void IOHIDManagerRegisterDeviceMatchingCallback(
+ IOHIDManagerRef inIOHIDManagerRef,
+ IntPtr inIOHIDDeviceCallback,
+ IntPtr inContext);
+
// This routine will be called when a (matching) device is disconnected.
[DllImport(hid)]
public static extern void IOHIDManagerRegisterDeviceRemovalCallback(
@@ -390,6 +406,12 @@ namespace OpenTK.Platform.MacOS
IOHIDDeviceCallback inIOHIDDeviceCallback,
IntPtr inContext);
+ [DllImport(hid)]
+ public static extern void IOHIDManagerRegisterDeviceRemovalCallback(
+ IOHIDManagerRef inIOHIDManagerRef,
+ IntPtr inIOHIDDeviceCallback,
+ IntPtr inContext);
+
[DllImport(hid)]
public static extern void IOHIDManagerScheduleWithRunLoop(
IOHIDManagerRef inIOHIDManagerRef,
@@ -428,6 +450,12 @@ namespace OpenTK.Platform.MacOS
IOHIDValueCallback callback,
IntPtr context);
+ [DllImport(hid)]
+ public static extern void IOHIDDeviceRegisterInputValueCallback(
+ IOHIDDeviceRef device,
+ IntPtr callback,
+ IntPtr context);
+
[DllImport(hid)]
public static extern void IOHIDDeviceScheduleWithRunLoop(
IOHIDDeviceRef device,
@@ -939,6 +967,59 @@ namespace OpenTK.Platform.MacOS
};
#endregion
+
+ #region IDisposable Members
+
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ NativeMethods.IOHIDManagerRegisterDeviceMatchingCallback(
+ hidmanager, IntPtr.Zero, IntPtr.Zero);
+ NativeMethods.IOHIDManagerRegisterDeviceRemovalCallback(
+ hidmanager, IntPtr.Zero, IntPtr.Zero);
+ NativeMethods.IOHIDManagerScheduleWithRunLoop(
+ hidmanager, IntPtr.Zero, IntPtr.Zero);
+
+ foreach (var device in MouseDevices.Keys)
+ {
+ NativeMethods.IOHIDDeviceRegisterInputValueCallback(
+ device, IntPtr.Zero, IntPtr.Zero);
+ }
+
+ foreach (var device in KeyboardDevices.Keys)
+ {
+ NativeMethods.IOHIDDeviceRegisterInputValueCallback(
+ device, IntPtr.Zero, IntPtr.Zero);
+ }
+
+ HandleDeviceAdded = null;
+ HandleDeviceRemoved = null;
+ HandleDeviceValueReceived = null;
+ }
+ else
+ {
+ Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~HIDInput()
+ {
+ Dispose(false);
+ }
+
+ #endregion
}
}
diff --git a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs
index 3bae0c4c..142ef76d 100644
--- a/Source/OpenTK/Platform/MacOS/MacOSFactory.cs
+++ b/Source/OpenTK/Platform/MacOS/MacOSFactory.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Text;
using OpenTK.Input;
@@ -38,6 +39,7 @@ namespace OpenTK.Platform.MacOS
{
#region Fields
+ bool disposed;
readonly IInputDriver2 InputDriver = new HIDInput();
#endregion
@@ -93,5 +95,36 @@ namespace OpenTK.Platform.MacOS
}
#endregion
+
+ #region IDisposable Members
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ InputDriver.Dispose();
+ }
+ else
+ {
+ Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~MacOSFactory()
+ {
+ Dispose(false);
+ }
+
+ #endregion
}
}
diff --git a/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs b/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs
index 357af984..ee569a06 100644
--- a/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs
+++ b/Source/OpenTK/Platform/SDL2/Sdl2Factory.cs
@@ -34,6 +34,7 @@ namespace OpenTK.Platform.SDL2
class Sdl2Factory : IPlatformFactory
{
readonly IInputDriver2 InputDriver = new Sdl2InputDriver();
+ bool disposed;
public Sdl2Factory()
{
@@ -102,6 +103,33 @@ namespace OpenTK.Platform.SDL2
}
#endregion
+
+ #region IDisposable Members
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ InputDriver.Dispose();
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~Sdl2Factory()
+ {
+ Dispose(false);
+ }
+
+ #endregion
}
}
diff --git a/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs b/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs
index cffb38a3..c8c1d368 100644
--- a/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs
+++ b/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs
@@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using OpenTK.Input;
@@ -38,6 +39,7 @@ namespace OpenTK.Platform.SDL2
readonly Sdl2Keyboard keyboard_driver = new Sdl2Keyboard();
readonly Sdl2Mouse mouse_driver = new Sdl2Mouse();
readonly SDL.SDL_EventFilter EventFilterDelegate;
+ bool disposed;
public Sdl2InputDriver()
{
@@ -109,6 +111,37 @@ namespace OpenTK.Platform.SDL2
}
#endregion
+
+ #region IDisposable Members
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ SDL.SDL_DelEventWatch(EventFilterDelegate, IntPtr.Zero);
+ }
+ else
+ {
+ Debug.WriteLine("Sdl2InputDriver leaked, did you forget to call Dispose()?");
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~Sdl2InputDriver()
+ {
+ Dispose(false);
+ }
+
+ #endregion
}
}
diff --git a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs
index 8e1142c4..7588073c 100644
--- a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs
+++ b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs
@@ -49,6 +49,7 @@ namespace OpenTK.Platform.SDL2
WindowState previous_window_state = WindowState.Normal;
WindowBorder window_border = WindowBorder.Resizable;
Icon icon;
+ string window_title;
KeyboardDevice keyboard = new KeyboardDevice();
MouseDevice mouse = new MouseDevice();
@@ -84,6 +85,7 @@ namespace OpenTK.Platform.SDL2
window = new Sdl2WindowInfo(handle, null);
window_id = SDL.SDL_GetWindowID(handle);
windows.Add(window_id, this);
+ window_title = title;
keyboard.Description = "Standard Windows keyboard";
keyboard.NumberOfFunctionKeys = 12;
@@ -227,6 +229,7 @@ namespace OpenTK.Platform.SDL2
{
exists = false;
+ SDL.SDL_DelEventWatch(EventFilterDelegate, IntPtr.Zero);
if (windows.ContainsKey(window_id))
{
windows.Remove(window_id);
@@ -245,10 +248,10 @@ namespace OpenTK.Platform.SDL2
SDL.SDL_SetRelativeMouseMode(
grab ? SDL.SDL_bool.SDL_TRUE : SDL.SDL_bool.SDL_FALSE);
- if (grab)
- {
- mouse.Position = new Point(0, 0);
- }
+ //if (grab)
+ //{
+ // mouse.Position = new Point(0, 0);
+ //}
}
// Hack to force WindowState events to be pumped
@@ -458,6 +461,7 @@ namespace OpenTK.Platform.SDL2
set
{
SDL.SDL_SetWindowTitle(window.Handle, value);
+ window_title = value;
}
}
diff --git a/Source/OpenTK/Platform/Windows/WMInput.cs b/Source/OpenTK/Platform/Windows/WMInput.cs
index 084f20fb..b4860dbe 100644
--- a/Source/OpenTK/Platform/Windows/WMInput.cs
+++ b/Source/OpenTK/Platform/Windows/WMInput.cs
@@ -49,10 +49,11 @@ namespace OpenTK.Platform.Windows
readonly object MouseLock = new object();
readonly object KeyboardLock = new object();
readonly WinMMJoystick gamepad_driver = new WinMMJoystick();
+ readonly WinKeyMap KeyMap = new WinKeyMap();
+
KeyboardState keyboard = new KeyboardState();
MouseState mouse = new MouseState();
-
- readonly WinKeyMap KeyMap = new WinKeyMap();
+ bool disposed;
#endregion
@@ -173,5 +174,36 @@ namespace OpenTK.Platform.Windows
}
#endregion
+
+ #region IDisposable Members
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ // Todo: implement this
+ }
+ else
+ {
+ Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~WMInput()
+ {
+ Dispose(false);
+ }
+
+ #endregion
}
}
diff --git a/Source/OpenTK/Platform/Windows/WinFactory.cs b/Source/OpenTK/Platform/Windows/WinFactory.cs
index 877d63f3..58f78ec6 100644
--- a/Source/OpenTK/Platform/Windows/WinFactory.cs
+++ b/Source/OpenTK/Platform/Windows/WinFactory.cs
@@ -37,6 +37,7 @@ namespace OpenTK.Platform.Windows
class WinFactory : IPlatformFactory
{
+ bool disposed;
readonly object SyncRoot = new object();
IInputDriver2 inputDriver;
@@ -123,5 +124,36 @@ namespace OpenTK.Platform.Windows
}
}
}
+
+ #region IDisposable Members
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ InputDriver.Dispose();
+ }
+ else
+ {
+ Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~WinFactory()
+ {
+ Dispose(false);
+ }
+
+ #endregion
}
}
diff --git a/Source/OpenTK/Platform/X11/X11Factory.cs b/Source/OpenTK/Platform/X11/X11Factory.cs
index e437e119..d62f618d 100644
--- a/Source/OpenTK/Platform/X11/X11Factory.cs
+++ b/Source/OpenTK/Platform/X11/X11Factory.cs
@@ -33,6 +33,8 @@ namespace OpenTK.Platform.X11
{
class X11Factory : IPlatformFactory
{
+ bool disposed;
+
#region Constructors
public X11Factory()
@@ -97,5 +99,36 @@ namespace OpenTK.Platform.X11
}
#endregion
+
+ #region IDisposable Members
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ if (manual)
+ {
+ // nothing to do
+ }
+ else
+ {
+ Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
+ }
+ disposed = true;
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ~X11Factory()
+ {
+ Dispose(false);
+ }
+
+ #endregion
}
}
diff --git a/Source/OpenTK/Toolkit.cs b/Source/OpenTK/Toolkit.cs
index 00085470..332ea375 100644
--- a/Source/OpenTK/Toolkit.cs
+++ b/Source/OpenTK/Toolkit.cs
@@ -1,79 +1,94 @@
-#region License
-//
-// The Open Toolkit Library License
-//
-// Copyright (c) 2006 - 2009 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.Text;
-
-namespace OpenTK
-{
- ///
- /// Provides static methods to manage an OpenTK application.
- ///
- public sealed class Toolkit
- {
- volatile static bool initialized;
- static readonly object InitLock = new object();
-
- #region Constructors
-
- Toolkit() { }
-
- #endregion
-
- #region Public Members
-
- ///
- /// Initializes OpenTK. This method is necessary only if you are using OpenTK
- /// alongside a different windowing toolkit (e.g. GTK#) and should be the very
- /// first method called by your application (i.e. calling this method should be
- /// the very first statement executed by the "Main" method).
- ///
- ///
- /// Some windowing toolkits do not configure the underlying platform
- /// correctly or configure it in a way that is incompatible with OpenTK.
- /// Calling this method first ensures that OpenTK is given the chance to
- /// initialize itself and configure the platform correctly.
- ///
- public static void Init()
- {
- lock (InitLock)
- {
- if (!initialized)
- {
- initialized = true;
- Configuration.Init();
- // The actual initialization takes place in the platform-specific factory
- // constructors.
- new Platform.Factory();
- }
- }
- }
-
- #endregion
- }
-}
+#region License
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2009 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.Text;
+using OpenTK.Platform;
+
+namespace OpenTK
+{
+ ///
+ /// Provides static methods to manage an OpenTK application.
+ ///
+ public sealed class Toolkit
+ {
+ static Factory platform_factory;
+
+ volatile static bool initialized;
+ static readonly object InitLock = new object();
+
+ #region Constructors
+
+ Toolkit() { }
+
+ #endregion
+
+ #region Public Members
+
+ ///
+ /// Initializes OpenTK. This method is necessary only if you are using OpenTK
+ /// alongside a different windowing toolkit (e.g. GTK#) and should be the very
+ /// first method called by your application (i.e. calling this method should be
+ /// the very first statement executed by the "Main" method).
+ ///
+ ///
+ /// Some windowing toolkits do not configure the underlying platform
+ /// correctly or configure it in a way that is incompatible with OpenTK.
+ /// Calling this method first ensures that OpenTK is given the chance to
+ /// initialize itself and configure the platform correctly.
+ ///
+ public static IDisposable Init()
+ {
+ lock (InitLock)
+ {
+ if (!initialized)
+ {
+ initialized = true;
+ Configuration.Init();
+ // The actual initialization takes place in the platform-specific factory
+ // constructors.
+ platform_factory = new Platform.Factory();
+ AppDomain.CurrentDomain.DomainUnload += Deinit;
+ }
+ return platform_factory;
+ }
+ }
+
+ #endregion
+
+ #region Private Members
+
+ static void Deinit(object sender, EventArgs e)
+ {
+ AppDomain.CurrentDomain.DomainUnload -= Deinit;
+ platform_factory.Dispose();
+ }
+
+ #endregion
+ }
+}