Serialize Sdl2NativeWindow methods

This change, along with moving DestroyWindow() to the Dispose() method
fixes crashes on shutdown.
This commit is contained in:
Stefanos A. 2013-10-03 14:59:30 +02:00
parent 3c867838e6
commit f2eda16458

View file

@ -38,6 +38,8 @@ namespace OpenTK.Platform.SDL2
{
class Sdl2NativeWindow : INativeWindow, IInputDriver
{
readonly object sync = new object();
Sdl2WindowInfo window;
uint window_id;
bool is_visible;
@ -65,6 +67,8 @@ namespace OpenTK.Platform.SDL2
public Sdl2NativeWindow(int x, int y, int width, int height,
string title, GameWindowFlags options, DisplayDevice device)
{
lock (sync)
{
var bounds = device.Bounds;
var flags = TranslateFlags(options);
@ -79,31 +83,29 @@ namespace OpenTK.Platform.SDL2
lock (SDL.Sync)
{
handle = SDL.SDL_CreateWindow(title, bounds.Left + x, bounds.Top + y, width, height, flags);
SDL.SDL_AddEventWatch(EventFilterDelegate, handle);
SDL.SDL_PumpEvents();
}
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.Description = "Standard keyboard";
keyboard.NumberOfFunctionKeys = 12;
keyboard.NumberOfKeys = 101;
keyboard.NumberOfLeds = 3;
mouse.Description = "Standard Windows mouse";
mouse.Description = "Standard mouse";
mouse.NumberOfButtons = 3;
mouse.NumberOfWheels = 1;
keyboards.Add(keyboard);
mice.Add(mouse);
lock (SDL.Sync)
{
SDL.SDL_AddEventWatch(EventFilterDelegate, handle);
}
exists = true;
}
}
#region Private Members
@ -141,7 +143,6 @@ namespace OpenTK.Platform.SDL2
try
{
Sdl2NativeWindow window = null;
SDL.SDL_Event ev = *(SDL.SDL_Event*)e;
@ -190,12 +191,7 @@ namespace OpenTK.Platform.SDL2
break;
case SDL.SDL_EventType.SDL_QUIT:
/*
if (windows.TryGetValue(ev.quit.windowID, out window))
{
}
*/
Debug.WriteLine("Sdl2 application quit");
break;
}
}
@ -270,7 +266,7 @@ namespace OpenTK.Platform.SDL2
if (!close_args.Cancel)
{
window.Closed(window, EventArgs.Empty);
window.DestroyWindow();
//window.DestroyWindow();
}
break;
@ -346,12 +342,12 @@ namespace OpenTK.Platform.SDL2
{
lock (SDL.Sync)
{
SDL.SDL_DestroyWindow(window.Handle);
SDL.SDL_DelEventWatch(EventFilterDelegate, window.Handle);
if (windows.ContainsKey(window_id))
{
windows.Remove(window_id);
}
SDL.SDL_DestroyWindow(window.Handle);
}
}
@ -425,12 +421,14 @@ namespace OpenTK.Platform.SDL2
public event EventHandler<EventArgs> MouseLeave = delegate { };
public void Close()
{
lock (sync)
{
if (Exists)
{
Debug.Print("SDL2 destroying window {0}", window.Handle);
SDL.SDL_Event e = new SDL.SDL_Event();
//e.type = SDL.SDL_EventType.SDL_QUIT;
e.type = SDL.SDL_EventType.SDL_WINDOWEVENT;
e.window.windowEvent = SDL.SDL_WindowEventID.SDL_WINDOWEVENT_CLOSE;
e.window.windowID = window_id;
@ -440,12 +438,13 @@ namespace OpenTK.Platform.SDL2
}
}
}
}
public void ProcessEvents()
{
if (Exists)
lock (sync)
{
lock (SDL.Sync)
if (Exists)
{
SDL.SDL_PumpEvents();
}
@ -473,6 +472,10 @@ namespace OpenTK.Platform.SDL2
return icon;
}
set
{
lock (sync)
{
if (Exists)
{
// Set the new icon, if any, or clear the current
// icon if null
@ -509,19 +512,34 @@ namespace OpenTK.Platform.SDL2
IconChanged(this, EventArgs.Empty);
}
}
}
}
public string Title
{
get
{
lock (sync)
{
if (Exists)
{
return SDL.SDL_GetWindowTitle(window.Handle);
}
return String.Empty;
}
}
set
{
lock (sync)
{
if (Exists)
{
SDL.SDL_SetWindowTitle(window.Handle, value);
window_title = value;
}
}
}
}
public bool Focused
{
@ -538,6 +556,10 @@ namespace OpenTK.Platform.SDL2
return is_visible;
}
set
{
lock (sync)
{
if (Exists)
{
if (value)
SDL.SDL_ShowWindow(window.Handle);
@ -545,6 +567,8 @@ namespace OpenTK.Platform.SDL2
SDL.SDL_HideWindow(window.Handle);
}
}
}
}
public bool Exists
{
@ -570,11 +594,12 @@ namespace OpenTK.Platform.SDL2
}
set
{
if (WindowState == value)
lock (sync)
{
if (Exists)
{
if (WindowState != value)
{
return;
}
// Set the new WindowState
switch (value)
{
@ -612,6 +637,9 @@ namespace OpenTK.Platform.SDL2
GrabCursor(true);
}
}
}
}
}
public WindowBorder WindowBorder
{
@ -621,8 +649,13 @@ namespace OpenTK.Platform.SDL2
}
set
{
if (value != WindowBorder)
if (WindowBorder != value)
{
lock (sync)
{
if (Exists)
{
switch (value)
{
case WindowBorder.Resizable:
@ -639,11 +672,16 @@ namespace OpenTK.Platform.SDL2
Debug.WriteLine("SDL2 cannot change to fixed-size windows at runtime.");
break;
}
}
}
if (Exists)
{
WindowBorderChanged(this, EventArgs.Empty);
}
}
}
}
public Rectangle Bounds
{
@ -661,30 +699,56 @@ namespace OpenTK.Platform.SDL2
public Point Location
{
get
{
lock (sync)
{
if (Exists)
{
int x, y;
SDL.SDL_GetWindowPosition(window.Handle, out x, out y);
return new Point(x, y);
}
return new Point();
}
}
set
{
lock (sync)
{
if (Exists)
{
SDL.SDL_SetWindowPosition(window.Handle, value.X, value.Y);
}
}
}
}
public Size Size
{
get
{
lock (sync)
{
if (Exists)
{
int w, h;
SDL.SDL_GetWindowSize(window.Handle, out w, out h);
return new Size(w, h);
}
return new Size();
}
}
set
{
lock (sync)
{
if (Exists)
{
SDL.SDL_SetWindowSize(window.Handle, value.Width, value.Height);
}
}
}
}
public int X
{
@ -777,11 +841,17 @@ namespace OpenTK.Platform.SDL2
return is_cursor_visible;
}
set
{
lock (sync)
{
if (Exists)
{
GrabCursor(!value);
is_cursor_visible = value;
}
}
}
}
#endregion
@ -789,7 +859,6 @@ namespace OpenTK.Platform.SDL2
public void Poll()
{
throw new NotImplementedException();
}
#endregion
@ -839,11 +908,14 @@ namespace OpenTK.Platform.SDL2
if (manual)
{
Debug.Print("Disposing {0}", GetType());
lock (sync)
{
if (Exists)
{
DestroyWindow();
}
}
}
else
{
Debug.WriteLine("Sdl2NativeWindow leaked, did you forget to call Dispose()?");