diff --git a/Source/OpenTK/GameWindow.cs b/Source/OpenTK/GameWindow.cs
index 1b690c0c..de49c4ca 100644
--- a/Source/OpenTK/GameWindow.cs
+++ b/Source/OpenTK/GameWindow.cs
@@ -275,7 +275,8 @@ namespace OpenTK
/// proper OpenTK shutdown.
///
public virtual void Exit()
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
//glWindow.DestroyWindow();
//while (glWindow.Exists)
// glWindow.ProcessEvents();
@@ -301,7 +302,8 @@ namespace OpenTK
///
public virtual void ExitAsync()
{
- //isExiting = true;
+ //isExiting = true;
+ if (disposed) throw new ObjectDisposedException("GameWindow");
UpdateFrame += CallExitInternal;
}
@@ -315,7 +317,7 @@ namespace OpenTK
///
public bool IsIdle
{
- get { return glWindow.IsIdle; }
+ get { if (disposed) throw new ObjectDisposedException("GameWindow"); return glWindow.IsIdle; }
}
#endregion
@@ -328,8 +330,8 @@ namespace OpenTK
///
public bool Fullscreen
{
- get { return glWindow.Fullscreen; }
- set { glWindow.Fullscreen = value; }
+ get { if (disposed) throw new ObjectDisposedException("GameWindow"); return glWindow.Fullscreen; }
+ set { if (disposed) throw new ObjectDisposedException("GameWindow"); glWindow.Fullscreen = value; }
}
#endregion
@@ -337,12 +339,15 @@ namespace OpenTK
#region public IGraphicsContext Context
///
- /// Returns the opengl IGLontext associated with the current GameWindow.
- /// Forces window creation.
+ /// Returns the opengl IGraphicsContext associated with the current GameWindow.
///
public IGraphicsContext Context
{
- get { return glContext; }
+ get
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
+ return glContext;
+ }
}
#endregion
@@ -367,11 +372,13 @@ namespace OpenTK
public string Title
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
return glWindow.Title;
}
set
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
glWindow.Title = value;
}
}
@@ -404,7 +411,7 @@ namespace OpenTK
public IWindowInfo WindowInfo
{
- get { return glWindow.WindowInfo; }
+ get { if (disposed) throw new ObjectDisposedException("GameWindow"); return glWindow.WindowInfo; }
}
#endregion
@@ -436,7 +443,8 @@ namespace OpenTK
/// (while the opengl context still exists), to allow resource cleanup.
///
public void DestroyWindow()
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (Exists)
glWindow.DestroyWindow();
else
@@ -452,7 +460,8 @@ namespace OpenTK
///
///
public void Run()
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
Run(0.0, 0.0);
}
@@ -462,7 +471,8 @@ namespace OpenTK
///
///
public void Run(double updateFrequency)
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
Run(updateFrequency, 0.0);
}
@@ -472,7 +482,8 @@ namespace OpenTK
/// The frequency of UpdateFrame events.
/// The frequency of RenderFrame events.
public void Run(double updates_per_second, double frames_per_second)
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
try
{
if (updates_per_second < 0.0 || updates_per_second > 200.0)
@@ -617,8 +628,9 @@ namespace OpenTK
if (Exists)
{
- glContext.Dispose();
- glWindow.DestroyWindow();
+ glContext.Dispose();
+ glContext = null;
+ glWindow.DestroyWindow();
}
while (this.Exists)
this.ProcessEvents();
@@ -641,7 +653,8 @@ namespace OpenTK
///
///
public void ProcessEvents()
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (!isExiting)
glWindow.InputDriver.Poll();
glWindow.ProcessEvents();
@@ -663,7 +676,7 @@ namespace OpenTK
///
///
private void OnRenderFrameInternal(RenderFrameEventArgs e)
- {
+ {
if (RenderFrame != null)
RenderFrame(this, e);
@@ -679,7 +692,8 @@ namespace OpenTK
/// The base implementation (base.OnRenderFrame) is empty, there is no need to call it.
///
public virtual void OnRenderFrame(RenderFrameEventArgs e)
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
}
///
@@ -717,7 +731,8 @@ namespace OpenTK
/// The base implementation (base.OnUpdateFrame) is empty, there is no need to call it.
///
public virtual void OnUpdateFrame(UpdateFrameEventArgs e)
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
}
///
@@ -767,7 +782,8 @@ namespace OpenTK
///
/// Not used.
public virtual void OnLoad(EventArgs e)
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
}
#endregion
@@ -799,7 +815,8 @@ namespace OpenTK
///
/// Not used.
public virtual void OnUnload(EventArgs e)
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
}
#endregion
@@ -814,7 +831,7 @@ namespace OpenTK
///
public bool IsExiting
{
- get { return isExiting; }
+ get { if (disposed) throw new ObjectDisposedException("GameWindow"); return isExiting; }
}
#endregion
@@ -827,7 +844,8 @@ namespace OpenTK
public KeyboardDevice Keyboard
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
//if (input_driver.Keyboard.Count > 0)
// return input_driver.Keyboard[0];
//else
@@ -850,7 +868,8 @@ namespace OpenTK
public MouseDevice Mouse
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
//if (input_driver.Mouse.Count > 0)
// return input_driver.Mouse[0];
//else
@@ -873,11 +892,13 @@ namespace OpenTK
public VSyncMode VSync
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
return vsync;
}
set
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (value == VSyncMode.Off)
Context.VSync = false;
else
@@ -897,7 +918,8 @@ namespace OpenTK
///
/// Calling this function is equivalent to calling Context.SwapBuffers()
public void SwapBuffers()
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
this.Context.SwapBuffers();
}
@@ -930,11 +952,13 @@ namespace OpenTK
public double TargetRenderPeriod
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
return target_render_period;
}
set
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (value <= 0.005)
{
target_render_period = target_render_period_doubled = 0.0;
@@ -962,13 +986,15 @@ namespace OpenTK
public double TargetRenderFrequency
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (TargetRenderPeriod == 0.0)
return 0.0;
return 1.0 / TargetRenderPeriod;
}
set
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (value < 1.0)
{
TargetRenderPeriod = 0.0;
@@ -995,11 +1021,13 @@ namespace OpenTK
public double TargetUpdatePeriod
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
return target_update_period;
}
set
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (value <= 0.005)
{
target_update_period = 0.0;
@@ -1026,13 +1054,15 @@ namespace OpenTK
public double TargetUpdateFrequency
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (TargetUpdatePeriod == 0.0)
return 0.0;
return 1.0 / TargetUpdatePeriod;
}
set
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (value < 1.0)
{
TargetUpdatePeriod = 0.0;
@@ -1055,7 +1085,8 @@ namespace OpenTK
public double RenderFrequency
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (render_period == 0.0)
return 1.0;
return 1.0 / render_period;
@@ -1072,7 +1103,8 @@ namespace OpenTK
public double RenderPeriod
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
return render_period;
}
}
@@ -1087,7 +1119,8 @@ namespace OpenTK
public double UpdateFrequency
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (update_period == 0.0)
return 1.0;
return 1.0 / update_period;
@@ -1104,7 +1137,8 @@ namespace OpenTK
public double UpdatePeriod
{
get
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
return update_period;
}
}
@@ -1118,8 +1152,8 @@ namespace OpenTK
///
public double RenderTime
{
- get { return render_time; }
- protected set { render_time = value; }
+ get { if (disposed) throw new ObjectDisposedException("GameWindow"); return render_time; }
+ protected set { if (disposed) throw new ObjectDisposedException("GameWindow"); render_time = value; }
}
#endregion
@@ -1131,7 +1165,7 @@ namespace OpenTK
///
public double UpdateTime
{
- get { return update_time; }
+ get { if (disposed) throw new ObjectDisposedException("GameWindow"); return update_time; }
}
#endregion
@@ -1147,9 +1181,10 @@ namespace OpenTK
///
public int Width
{
- get { return width; }
+ get { if (disposed) throw new ObjectDisposedException("GameWindow"); return width; }
set
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (value == this.Width)
{
return;
@@ -1174,9 +1209,10 @@ namespace OpenTK
///
public int Height
{
- get { return height; }
+ get { if (disposed) throw new ObjectDisposedException("GameWindow"); return height; }
set
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
if (value == this.Height)
{
return;
@@ -1205,8 +1241,8 @@ namespace OpenTK
///
public event ResizeEvent Resize
{
- add { glWindow.Resize += value; }
- remove { glWindow.Resize -= value; }
+ add { if (disposed) throw new ObjectDisposedException("GameWindow"); glWindow.Resize += value; }
+ remove { if (disposed) throw new ObjectDisposedException("GameWindow"); glWindow.Resize -= value; }
}
///
@@ -1231,7 +1267,8 @@ namespace OpenTK
///
/// Contains information about the Resize event.
protected virtual void OnResize(ResizeEventArgs e)
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
}
#endregion
@@ -1303,21 +1340,14 @@ namespace OpenTK
#endif
#region --- IDisposable Members ---
- ///
- /// Not used yet.
- ///
- private void DisposeInternal()
- {
- Dispose(); // User overridable Dispose method.
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
///
/// Disposes of the GameWindow, releasing all resources consumed by it.
///
public virtual void Dispose()
- {
+ {
+ if (disposed) throw new ObjectDisposedException("GameWindow");
+ Dispose(true);
+ GC.SuppressFinalize(this);
}
private void Dispose(bool manual)
@@ -1326,8 +1356,11 @@ namespace OpenTK
{
if (manual)
{
- if (glContext != null)
- glContext.Dispose();
+ if (glContext != null)
+ {
+ glContext.Dispose();
+ glContext = null;
+ }
if (glWindow != null)
{
@@ -1340,10 +1373,10 @@ namespace OpenTK
}
/// Finalizes unmanaged resources consumed by the GameWindow.
- ~GameWindow()
- {
- Dispose(false);
- }
+ //~GameWindow()
+ //{
+ // Dispose(false);
+ //}
#endregion
}
diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs
index c601a736..81cb7fa6 100644
--- a/Source/OpenTK/Graphics/GraphicsContext.cs
+++ b/Source/OpenTK/Graphics/GraphicsContext.cs
@@ -83,8 +83,11 @@ namespace OpenTK.Graphics
implementation = new OpenTK.Platform.X11.X11GLContext(mode, window, shareContext, DirectRendering);
else
throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information.");
-
- available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
+
+ lock (context_lock)
+ {
+ available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
+ }
//(implementation as IGraphicsContextInternal).LoadAll();
}
@@ -118,14 +121,17 @@ namespace OpenTK.Graphics
public static GraphicsContext CurrentContext
{
get
- {
- if (available_contexts.Count > 0)
+ {
+ lock (context_lock)
{
- ContextHandle handle = GetCurrentContext();
- if (handle.Handle != IntPtr.Zero)
- return (GraphicsContext)available_contexts[handle].Target;
+ if (available_contexts.Count > 0)
+ {
+ ContextHandle handle = GetCurrentContext();
+ if (handle.Handle != IntPtr.Zero)
+ return (GraphicsContext)available_contexts[handle].Target;
+ }
+ return null;
}
- return null;
}
//set
//{
@@ -199,8 +205,11 @@ namespace OpenTK.Graphics
void CreateContext(bool direct, IGraphicsContext source)
{
this.Destroy += ContextDestroyed;
-
- available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
+
+ lock (context_lock)
+ {
+ available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
+ }
//OpenTK.Graphics.OpenGL.GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit);
//if (StaticGetCurrentContext == null)
@@ -363,13 +372,15 @@ namespace OpenTK.Graphics
void Dispose(bool manual)
{
if (!disposed)
- {
+ {
+ Debug.WriteLine("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString());
+ lock (context_lock)
+ {
+ available_contexts.Remove((this as IGraphicsContextInternal).Context);
+ }
+
if (manual)
{
- Debug.WriteLine("Disposing context.");
- available_contexts.Remove((this as IGraphicsContextInternal).Context);
-
- // TODO: Check if this is safe
if (implementation != null)
implementation.Dispose();
}
@@ -377,10 +388,10 @@ namespace OpenTK.Graphics
}
}
- ~GraphicsContext()
- {
- this.Dispose(false);
- }
+ //~GraphicsContext()
+ //{
+ // this.Dispose(false);
+ //}
#endregion
}
@@ -398,4 +409,4 @@ namespace OpenTK.Graphics
}
#endregion
-}
\ No newline at end of file
+}
diff --git a/Source/OpenTK/Platform/X11/API.cs b/Source/OpenTK/Platform/X11/API.cs
index 66da0f21..003284b1 100644
--- a/Source/OpenTK/Platform/X11/API.cs
+++ b/Source/OpenTK/Platform/X11/API.cs
@@ -66,7 +66,9 @@ namespace OpenTK.Platform.X11
#endregion
static API()
- {
+ {
+ Debug.Print("Initializing threaded X11: {0}.", Functions.XInitThreads().ToString());
+
AppDomain.CurrentDomain.ProcessExit += new EventHandler(CurrentDomain_ProcessExit);
// Bad idea - Windows.Forms will steal our events!
diff --git a/Source/OpenTK/Platform/X11/Functions.cs b/Source/OpenTK/Platform/X11/Functions.cs
index 0e23e3f3..565925c0 100644
--- a/Source/OpenTK/Platform/X11/Functions.cs
+++ b/Source/OpenTK/Platform/X11/Functions.cs
@@ -40,6 +40,35 @@ namespace OpenTK.Platform.X11
using Status = System.Int32;
using SizeID = System.UInt16;
+ #endregion
+
+ #region DisplayLock
+
+ /*
+ internal class DisplayLock : IDisposable
+ {
+ IntPtr display;
+
+ public DisplayLock(IntPtr display)
+ {
+ if (display == IntPtr.Zero) throw new ArgumentException("display", "Must be a valid X11 display connection.");
+ this.display = display;
+ Functions.XLockDisplay(display);
+ }
+
+ publc void Dispose()
+ {
+ Functions.XUnlockDisplay(display);
+ GC.SuppressFinalize(this);
+ }
+
+ ~DisplayLock()
+ {
+ Functions.XUnlockDisplay(display);
+ }
+ }
+ */
+
#endregion
internal static partial class Functions
@@ -382,7 +411,12 @@ namespace OpenTK.Platform.X11
}
[DllImport("libX11")]
- public static extern IntPtr XCreateColormap(Display display, Window window, IntPtr visual, int alloc);
-
+ public static extern IntPtr XCreateColormap(Display display, Window window, IntPtr visual, int alloc);
+
+ [DllImport("libX11")]
+ public static extern void XLockDisplay(Display display);
+
+ [DllImport("libX11")]
+ public static extern void XUnlockDisplay(Display display);
}
}
diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs
index d2a31791..134e22f0 100644
--- a/Source/OpenTK/Platform/X11/X11GLContext.cs
+++ b/Source/OpenTK/Platform/X11/X11GLContext.cs
@@ -63,13 +63,18 @@ namespace OpenTK.Platform.X11
XVisualInfo info = new XVisualInfo();
info.visualid = (IntPtr)mode.Index;
info.screen = currentWindow.Screen;
- int items;
- IntPtr vs = Functions.XGetVisualInfo(currentWindow.Display, XVisualInfoMask.ID | XVisualInfoMask.Screen, ref info, out items);
- if (items == 0)
- throw new GraphicsModeException(String.Format("Invalid GraphicsMode specified ({0}).", mode));
+ int items;
+
+ lock (API.Lock)
+ {
+ IntPtr vs = Functions.XGetVisualInfo(currentWindow.Display, XVisualInfoMask.ID | XVisualInfoMask.Screen, ref info, out items);
+ if (items == 0)
+ throw new GraphicsModeException(String.Format("Invalid GraphicsMode specified ({0}).", mode));
+
+ info = (XVisualInfo)Marshal.PtrToStructure(vs, typeof(XVisualInfo));
+ Functions.XFree(vs);
+ }
- info = (XVisualInfo)Marshal.PtrToStructure(vs, typeof(XVisualInfo));
- Functions.XFree(vs);
return info;
}
@@ -88,26 +93,29 @@ namespace OpenTK.Platform.X11
Debug.Write(direct ? "direct, " : "indirect, ");
Debug.Write(shareHandle.Handle == IntPtr.Zero ? "not shared... " :
String.Format("shared with ({0})... ", shareHandle));
+
+ lock (API.Lock)
+ {
+ XVisualInfo info = window.VisualInfo; // Cannot pass a Property by reference.
+ context = Glx.CreateContext(window.Display, ref info, shareHandle.Handle, direct);
- XVisualInfo info = window.VisualInfo; // Cannot pass a Property by reference.
- context = Glx.CreateContext(window.Display, ref info, shareHandle.Handle, direct);
+ // Context creation succeeded, return.
+ if (context != IntPtr.Zero)
+ {
+ Debug.Print("done! (id: {0})", context);
+ return;
+ }
- // Context creation succeeded, return.
- if (context != IntPtr.Zero)
- {
- Debug.Print("done! (id: {0})", context);
- return;
- }
-
- // Context creation failed. Retry with a non-shared context with the direct/indirect bit flipped.
- Debug.Print("failed.");
- Debug.Write(String.Format("Creating OpenGL context: {0}, not shared... ", !direct ? "direct" : "indirect"));
- context = Glx.CreateContext(window.Display, ref info, IntPtr.Zero, !direct);
- if (context != IntPtr.Zero)
- {
- Debug.Print("done! (id: {0})", context);
- return;
- }
+ // Context creation failed. Retry with a non-shared context with the direct/indirect bit flipped.
+ Debug.Print("failed.");
+ Debug.Write(String.Format("Creating OpenGL context: {0}, not shared... ", !direct ? "direct" : "indirect"));
+ context = Glx.CreateContext(window.Display, ref info, IntPtr.Zero, !direct);
+ if (context != IntPtr.Zero)
+ {
+ Debug.Print("done! (id: {0})", context);
+ return;
+ }
+ }
Debug.Print("failed.");
throw new GraphicsModeException("Failed to create OpenGL context. Glx.CreateContext call returned 0.");
@@ -194,10 +202,10 @@ namespace OpenTK.Platform.X11
set
{
if (vsync_supported)
- {
+ {
int error_code = Glx.Sgi.SwapInterval(value ? 1 : 0);
if (error_code != 0)
- throw new GraphicsException(String.Format("Could not set vsync, error code: {0}", error_code));
+ throw new GraphicsException(String.Format("Could not set vsync, error code: {0}", error_code));
vsync_interval = value ? 1 : 0;
}
}
@@ -286,7 +294,7 @@ namespace OpenTK.Platform.X11
#region static ContextHandle GetCurrentContext()
static ContextHandle GetCurrentContext()
- {
+ {
return (ContextHandle)Glx.GetCurrentContext();
}
@@ -305,16 +313,22 @@ namespace OpenTK.Platform.X11
private void Dispose(bool manuallyCalled)
{
if (!disposed)
- {
+ {
// Clean unmanaged resources:
-
- Glx.MakeCurrent(currentWindow.Display, IntPtr.Zero, IntPtr.Zero);
- Glx.DestroyContext(currentWindow.Display, context);
- //API.Free(visual);
-
+ try
+ {
+ Functions.XLockDisplay(currentWindow.Display);
+ Glx.MakeCurrent(currentWindow.Display, IntPtr.Zero, IntPtr.Zero);
+ Glx.DestroyContext(currentWindow.Display, context);
+ //Functions.XFree(visual);
+ }
+ finally
+ {
+ Functions.XUnlockDisplay(currentWindow.Display);
+ }
+
if (manuallyCalled)
{
- // Safe to clean managed resources, too
}
}
disposed = true;
diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs
index a4a465b6..6e5628e8 100644
--- a/Source/OpenTK/Platform/X11/X11GLNative.cs
+++ b/Source/OpenTK/Platform/X11/X11GLNative.cs
@@ -94,12 +94,22 @@ namespace OpenTK.Platform.X11
//window.Screen = (int)xplatui.GetField("ScreenNo",
// System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
- // Open a display connection to the X server, and obtain the screen and root window.
- window.Display = API.DefaultDisplay;//Functions.XOpenDisplay(IntPtr.Zero); // IntPtr.Zero == default display
+ // Open a display connection to the X server, and obtain the screen and root window.
+ window.Display = API.DefaultDisplay;//Functions.XOpenDisplay(IntPtr.Zero); // IntPtr.Zero == default display
if (window.Display == IntPtr.Zero)
throw new Exception("Could not open connection to X");
- window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
- window.RootWindow = Functions.XRootWindow(window.Display, window.Screen); // API.RootWindow;
+
+ try
+ {
+ Functions.XLockDisplay(window.Display);
+ window.Screen = Functions.XDefaultScreen(window.Display); //API.DefaultScreen;
+ window.RootWindow = Functions.XRootWindow(window.Display, window.Screen); // API.RootWindow;
+ }
+ finally
+ {
+ Functions.XUnlockDisplay(window.Display);
+ }
+
Debug.Print("Display: {0}, Screen {1}, Root window: {2}", window.Display, window.Screen, window.RootWindow);
RegisterAtoms(window);
@@ -144,57 +154,61 @@ namespace OpenTK.Platform.X11
if (width <= 0) throw new ArgumentOutOfRangeException("width", "Must be higher than zero.");
if (height <= 0) throw new ArgumentOutOfRangeException("height", "Must be higher than zero.");
if (exists) throw new InvalidOperationException("A render window already exists.");
+
+ XVisualInfo info = new XVisualInfo();
- Debug.Indent();
+ Debug.Indent();
+
+ lock (API.Lock)
+ {
+ info.visualid = mode.Index;
+ int dummy;
+ window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure(
+ Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo));
- XVisualInfo info = new XVisualInfo();
- info.visualid = mode.Index;
- int dummy;
- window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure(
- Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo));
+ // Create a window on this display using the visual above
+ Debug.Write("Opening render window... ");
- // Create a window on this display using the visual above
- Debug.Write("Opening render window... ");
+ XSetWindowAttributes attributes = new XSetWindowAttributes();
+ attributes.background_pixel = IntPtr.Zero;
+ attributes.border_pixel = IntPtr.Zero;
+ attributes.colormap = Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/);
+ window.EventMask = EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
+ EventMask.KeyReleaseMask | EventMask.KeyPressMask |
+ EventMask.PointerMotionMask | // Bad! EventMask.PointerMotionHintMask |
+ EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
+ attributes.event_mask = (IntPtr)window.EventMask;
- XSetWindowAttributes attributes = new XSetWindowAttributes();
- attributes.background_pixel = IntPtr.Zero;
- attributes.border_pixel = IntPtr.Zero;
- attributes.colormap = Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/);
- window.EventMask = EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
- EventMask.KeyReleaseMask | EventMask.KeyPressMask |
- EventMask.PointerMotionMask | // Bad! EventMask.PointerMotionHintMask |
- EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
- attributes.event_mask = (IntPtr)window.EventMask;
+ uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
+ (uint)SetWindowValuemask.BackPixel | (uint)SetWindowValuemask.BorderPixel;
- uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
- (uint)SetWindowValuemask.BackPixel | (uint)SetWindowValuemask.BorderPixel;
+ window.WindowHandle = Functions.XCreateWindow(window.Display, window.RootWindow,
+ 0, 0, width, height, 0, window.VisualInfo.depth/*(int)CreateWindowArgs.CopyFromParent*/,
+ (int)CreateWindowArgs.InputOutput, window.VisualInfo.visual, (UIntPtr)mask, ref attributes);
- window.WindowHandle = Functions.XCreateWindow(window.Display, window.RootWindow,
- 0, 0, width, height, 0, window.VisualInfo.depth/*(int)CreateWindowArgs.CopyFromParent*/,
- (int)CreateWindowArgs.InputOutput, window.VisualInfo.visual, (UIntPtr)mask, ref attributes);
-
- if (window.WindowHandle == IntPtr.Zero)
- throw new ApplicationException("XCreateWindow call failed (returned 0).");
-
- //XVisualInfo vis = window.VisualInfo;
- //Glx.CreateContext(window.Display, ref vis, IntPtr.Zero, true);
+ if (window.WindowHandle == IntPtr.Zero)
+ throw new ApplicationException("XCreateWindow call failed (returned 0).");
+ //XVisualInfo vis = window.VisualInfo;
+ //Glx.CreateContext(window.Display, ref vis, IntPtr.Zero, true);
+ }
context = new GraphicsContext(mode, window);
-
+
// Set the window hints
XSizeHints hints = new XSizeHints();
hints.x = 0;
hints.y = 0;
hints.width = width;
hints.height = height;
- hints.flags = (IntPtr)(XSizeHintsFlags.USSize | XSizeHintsFlags.USPosition);
- Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints);
-
- // Register for window destroy notification
- IntPtr wm_destroy_atom = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true);
- //XWMHints hint = new XWMHints();
- Functions.XSetWMProtocols(window.Display, window.WindowHandle, new IntPtr[] { wm_destroy_atom }, 1);
+ hints.flags = (IntPtr)(XSizeHintsFlags.USSize | XSizeHintsFlags.USPosition);
+ lock (API.Lock)
+ {
+ Functions.XSetWMNormalHints(window.Display, window.WindowHandle, ref hints);
+ // Register for window destroy notification
+ IntPtr wm_destroy_atom = Functions.XInternAtom(window.Display, "WM_DELETE_WINDOW", true);
+ Functions.XSetWMProtocols(window.Display, window.WindowHandle, new IntPtr[] { wm_destroy_atom }, 1);
+ }
Top = Left = 0;
Right = Width;
Bottom = Height;
@@ -206,10 +220,11 @@ namespace OpenTK.Platform.X11
//Functions.XSetWMProperties(display, window, name, name, 0, /*None*/ null, 0, hints);
Debug.Print("done! (id: {0})", window.WindowHandle);
-
- //(glContext as IGLContextCreationHack).SetWindowHandle(window.Handle);
-
- API.MapRaised(window.Display, window.WindowHandle);
+
+ lock (API.Lock)
+ {
+ API.MapRaised(window.Display, window.WindowHandle);
+ }
mapped = true;
//context.CreateContext(true, null);
@@ -663,18 +678,24 @@ namespace OpenTK.Platform.X11
private void Dispose(bool manuallyCalled)
{
if (!disposed)
- {
- if (window != null)
+ {
+ if (window != null && window.WindowHandle != IntPtr.Zero)
{
- if (window.WindowHandle != IntPtr.Zero)
- Functions.XDestroyWindow(window.Display, window.WindowHandle);
- //if (window.Display != IntPtr.Zero)
- // Functions.XCloseDisplay(window.Display);
+ try
+ {
+ Functions.XLockDisplay(window.Display);
+ Functions.XDestroyWindow(window.Display, window.WindowHandle);
+ }
+ finally
+ {
+ Functions.XUnlockDisplay(window.Display);
+ }
+
window = null;
}
-
+
if (manuallyCalled)
- {
+ {
}
disposed = true;
}
diff --git a/Source/OpenTK/Platform/X11/X11GraphicsMode.cs b/Source/OpenTK/Platform/X11/X11GraphicsMode.cs
index d51bfa72..86864c91 100644
--- a/Source/OpenTK/Platform/X11/X11GraphicsMode.cs
+++ b/Source/OpenTK/Platform/X11/X11GraphicsMode.cs
@@ -80,9 +80,12 @@ namespace OpenTK.Platform.X11
visualAttributes.Add((int)0);
// Select a visual that matches the parameters set by the user.
- lock (API.Lock)
- {
- IntPtr display = API.DefaultDisplay; //Functions.XOpenDisplay(IntPtr.Zero);
+ IntPtr display = API.DefaultDisplay; //Functions.XOpenDisplay(IntPtr.Zero);
+
+ try
+ {
+ Functions.XLockDisplay(display);
+
int screen = Functions.XDefaultScreen(display);
IntPtr root = Functions.XRootWindow(display, screen);
Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
@@ -112,24 +115,26 @@ namespace OpenTK.Platform.X11
++buffers; // the above lines returns 0 - false and 1 - true.
int st;
Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
- stereo = st != 0;
-
+ stereo = st != 0;
+
gfx = new GraphicsMode(info.visualid, new ColorFormat(r, g, b, a), depth, stencil, samples,
- new ColorFormat(ar, ag, ab, aa), buffers, stereo);
-
- //Functions.XCloseDisplay(display);
+ new ColorFormat(ar, ag, ab, aa), buffers, stereo);
+ }
+ finally
+ {
+ Functions.XUnlockDisplay(display);
}
// Prepare Windows.Forms for creating OpenGL drawables.
- lock (API.Lock)
- {
- Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
- IntPtr display = (IntPtr)xplatui.GetField("DisplayHandle",
- System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
- IntPtr root = (IntPtr)xplatui.GetField("RootWindow",
- System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
- int screen = (int)xplatui.GetField("ScreenNo",
- System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ //lock (API.Lock)
+ //{
+ // Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
+ // IntPtr display = (IntPtr)xplatui.GetField("DisplayHandle",
+ // System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ // IntPtr root = (IntPtr)xplatui.GetField("RootWindow",
+ // System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
+ // int screen = (int)xplatui.GetField("ScreenNo",
+ // System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
//xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
@@ -137,9 +142,17 @@ namespace OpenTK.Platform.X11
//xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
// .SetValue(null, Functions.XCreateColormap(display, root, visual, 0));
- }
+ //}
- Functions.XFree(visual);
+ try
+ {
+ Functions.XLockDisplay(display);
+ Functions.XFree(visual);
+ }
+ finally
+ {
+ Functions.XUnlockDisplay(display);
+ }
return gfx;
}