From 48803bb4d620009ea3b9aab6981f6800a2b3793e Mon Sep 17 00:00:00 2001 From: "Stefanos A." Date: Wed, 20 Nov 2013 09:10:12 +0100 Subject: [PATCH] Fixed #4 Sdl2InputDriver.Dispose() would call SDL_DelEventWatch with a different "user_data" parameter than SDL_AdEventWatch. This caused the EventFilter to remain registered and subsequently crash when closing and reopening a window. --- Source/OpenTK/Platform/SDL2/Sdl2.cs | 8 ++++++++ Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs | 6 ++++-- Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs | 4 +++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Source/OpenTK/Platform/SDL2/Sdl2.cs b/Source/OpenTK/Platform/SDL2/Sdl2.cs index 2ec6c2a7..9e9e0a56 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2.cs @@ -83,6 +83,10 @@ namespace OpenTK.Platform.SDL2 [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_AddEventWatch", ExactSpelling = true)] public static extern void AddEventWatch(EventFilter filter, IntPtr userdata); + [SuppressUnmanagedCodeSecurity] + [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_AddEventWatch", ExactSpelling = true)] + public static extern void AddEventWatch(IntPtr filter, IntPtr userdata); + [SuppressUnmanagedCodeSecurity] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_CreateRGBSurfaceFrom", ExactSpelling = true)] public static extern IntPtr CreateRGBSurfaceFrom(IntPtr pixels, @@ -102,6 +106,10 @@ namespace OpenTK.Platform.SDL2 [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_DelEventWatch", ExactSpelling = true)] public static extern void DelEventWatch(EventFilter filter, IntPtr userdata); + [SuppressUnmanagedCodeSecurity] + [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_DelEventWatch", ExactSpelling = true)] + public static extern void DelEventWatch(IntPtr filter, IntPtr userdata); + [SuppressUnmanagedCodeSecurity] [DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_DestroyWindow", ExactSpelling = true)] public static extern void DestroyWindow(IntPtr window); diff --git a/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs b/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs index 6c9bb529..7a571b14 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2InputDriver.cs @@ -45,7 +45,8 @@ namespace OpenTK.Platform.SDL2 readonly Sdl2Mouse mouse_driver = new Sdl2Mouse(); readonly Sdl2JoystickDriver joystick_driver = new Sdl2JoystickDriver(); - readonly EventFilter EventFilterDelegate = FilterInputEvents; + readonly EventFilter EventFilterDelegate_GCUnsafe = FilterInputEvents; + readonly IntPtr EventFilterDelegate; static int count; bool disposed; @@ -54,6 +55,7 @@ namespace OpenTK.Platform.SDL2 { lock (SDL.Sync) { + EventFilterDelegate = Marshal.GetFunctionPointerForDelegate(EventFilterDelegate_GCUnsafe); driver_handle = new IntPtr(count++); DriverHandles.Add(driver_handle, this); SDL.AddEventWatch(EventFilterDelegate, driver_handle); @@ -188,7 +190,7 @@ namespace OpenTK.Platform.SDL2 joystick_driver.Dispose(); lock (SDL.Sync) { - SDL.DelEventWatch(EventFilterDelegate, IntPtr.Zero); + SDL.DelEventWatch(EventFilterDelegate, driver_handle); } DriverHandles.Remove(driver_handle); } diff --git a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs index 8e0c4f12..e28e2372 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs @@ -59,7 +59,8 @@ namespace OpenTK.Platform.SDL2 readonly IInputDriver input_driver = new Sdl2InputDriver(); - readonly EventFilter EventFilterDelegate = FilterEvents; + readonly EventFilter EventFilterDelegate_GCUnsafe = FilterEvents; + readonly IntPtr EventFilterDelegate; static readonly Dictionary windows = new Dictionary(); @@ -85,6 +86,7 @@ namespace OpenTK.Platform.SDL2 IntPtr handle; lock (SDL.Sync) { + EventFilterDelegate = Marshal.GetFunctionPointerForDelegate(EventFilterDelegate_GCUnsafe); handle = SDL.CreateWindow(title, bounds.Left + x, bounds.Top + y, width, height, flags); SDL.AddEventWatch(EventFilterDelegate, handle); SDL.PumpEvents();