From 0b5a0b4e1f457822f04c20aae3236e10ba1f6452 Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Tue, 21 Aug 2007 10:48:32 +0000 Subject: [PATCH] Improved X11GLControl compatibility - now sets a safe DisplayMode. Added utility that control's whether xplatui should throw exceptions on X11 errors. --- Source/Examples/WinForms/W01_First_Window.cs | 10 +- Source/OpenTK/GLControl.cs | 35 ++++--- Source/OpenTK/Platform/Utilities.cs | 23 +++++ Source/OpenTK/Platform/X11/X11GLContext.cs | 64 ++++++------- Source/OpenTK/Platform/X11/X11GLControl.cs | 96 +++----------------- Source/OpenTK/Platform/X11/X11GLNative.cs | 10 +- 6 files changed, 101 insertions(+), 137 deletions(-) diff --git a/Source/Examples/WinForms/W01_First_Window.cs b/Source/Examples/WinForms/W01_First_Window.cs index e5c2659a..3b89e8d3 100644 --- a/Source/Examples/WinForms/W01_First_Window.cs +++ b/Source/Examples/WinForms/W01_First_Window.cs @@ -25,7 +25,15 @@ namespace Examples.WinForms { public W01_First_Window() { - InitializeComponent(); + try + { + InitializeComponent(); + } + catch (Exception e) + { + System.Diagnostics.Trace.WriteLine("Exception during initialization, aborting: {0}", e.ToString()); + return; + } this.ShowDialog(); } diff --git a/Source/OpenTK/GLControl.cs b/Source/OpenTK/GLControl.cs index e4e010fd..4e817595 100644 --- a/Source/OpenTK/GLControl.cs +++ b/Source/OpenTK/GLControl.cs @@ -92,23 +92,34 @@ namespace OpenTK /// public void CreateContext() { - if (Environment.OSVersion.Platform == PlatformID.Win32NT || - Environment.OSVersion.Platform == PlatformID.Win32Windows) + try { - glControl = new OpenTK.Platform.Windows.WinGLControl(this, new DisplayMode(Width, Height)); + if (Environment.OSVersion.Platform == PlatformID.Win32NT || + Environment.OSVersion.Platform == PlatformID.Win32Windows) + { + glControl = new OpenTK.Platform.Windows.WinGLControl(this, new DisplayMode(Width, Height)); + } + else if (Environment.OSVersion.Platform == PlatformID.Unix || + Environment.OSVersion.Platform == (PlatformID)128) // some older versions of Mono reported 128. + { + glControl = new OpenTK.Platform.X11.X11GLControl(this); + //, new DisplayMode(this.Width, this.Height, new OpenTK.Platform.ColorDepth(1, 1, 1, 1), 1, 0, 0, 0, false, false, false, 0.0f)); + } + else + { + throw new PlatformNotSupportedException( + "Your operating system is not currently supported. We are sorry for the inconvenience." + ); + } } - else if (Environment.OSVersion.Platform == PlatformID.Unix || - Environment.OSVersion.Platform == (PlatformID)128) // some older versions of Mono reported 128. + catch (Exception e) { - glControl = new OpenTK.Platform.X11.X11GLControl(this, new DisplayMode(Width, Height)); - } - else - { - throw new PlatformNotSupportedException( - "Your operating system is not currently supported. We are sorry for the inconvenience." - ); + Debug.Print("Could not create GLControl, error: {0}", e.ToString()); + throw; } + this.Visible = true; + OpenTK.OpenGL.GL.LoadAll(); this.OnResize(EventArgs.Empty); } diff --git a/Source/OpenTK/Platform/Utilities.cs b/Source/OpenTK/Platform/Utilities.cs index 4f243ee0..1d6801c6 100644 --- a/Source/OpenTK/Platform/Utilities.cs +++ b/Source/OpenTK/Platform/Utilities.cs @@ -166,5 +166,28 @@ namespace OpenTK.Platform } #endregion + + static bool throw_on_error; + internal static bool ThrowOnX11Error + { + get { return throw_on_error; } + set + { + if (value && !throw_on_error) + { + Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms") + .GetField("ErrorExceptions", System.Reflection.BindingFlags.Static | + System.Reflection.BindingFlags.NonPublic) + .SetValue(null, true); + } + else if (!value && throw_on_error) + { + Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms") + .GetField("ErrorExceptions", System.Reflection.BindingFlags.Static | + System.Reflection.BindingFlags.NonPublic) + .SetValue(null, false); + } + } + } } } diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index 6dd92eb9..11374a2c 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -20,16 +20,10 @@ namespace OpenTK.Platform.X11 public sealed class X11GLContext : OpenTK.Platform.IGLContext { private IntPtr context; - private DisplayMode mode;// = new DisplayMode(); + private DisplayMode mode; internal WindowInfo windowInfo; - //private IntPtr desktopResolution = IntPtr.Zero; - - //private int depthBits; - //private int stencilBits; - - // These have to be used by the X11GLControl. - private IntPtr visual; + internal IntPtr visual; private bool disposed; @@ -74,26 +68,38 @@ namespace OpenTK.Platform.X11 { this.windowInfo = new WindowInfo(info); - Debug.Print("Preparing visual for DisplayMode: {0}", mode.ToString()); - List visualAttributes = new List(); - visualAttributes.Add((int)Glx.Enums.GLXAttribute.RGBA); - visualAttributes.Add((int)Glx.Enums.GLXAttribute.RED_SIZE); - visualAttributes.Add((int)mode.Color.Red); - visualAttributes.Add((int)Glx.Enums.GLXAttribute.GREEN_SIZE); - visualAttributes.Add((int)mode.Color.Green); - visualAttributes.Add((int)Glx.Enums.GLXAttribute.BLUE_SIZE); - visualAttributes.Add((int)mode.Color.Blue); - //visualAttributes.Add((int)Glx.Enums.GLXAttribute.ALPHA_SIZE); - //visualAttributes.Add((int)mode.Color.Alpha); - visualAttributes.Add((int)Glx.Enums.GLXAttribute.DEPTH_SIZE); - visualAttributes.Add((int)mode.DepthBits); - visualAttributes.Add((int)1); - visualAttributes.Add((int)Glx.Enums.GLXAttribute.DOUBLEBUFFER); - visualAttributes.Add((int)0); - //try - //{ + if (mode == null) + { + // Define the bare essentials - needed for compatibility with Mono's System.Windows.Forms + Debug.Print("Preparing visual for System.Windows.Forms (compatibility mode)"); + + visualAttributes.Add((int)Glx.Enums.GLXAttribute.RGBA); + visualAttributes.Add((int)Glx.Enums.GLXAttribute.DEPTH_SIZE); + visualAttributes.Add((int)1); + visualAttributes.Add((int)Glx.Enums.GLXAttribute.DOUBLEBUFFER); + visualAttributes.Add((int)0); + } + else + { + Debug.Print("Preparing visual for DisplayMode: {0}", mode.ToString()); + + visualAttributes.Add((int)Glx.Enums.GLXAttribute.RGBA); + visualAttributes.Add((int)Glx.Enums.GLXAttribute.RED_SIZE); + visualAttributes.Add((int)mode.Color.Red); + visualAttributes.Add((int)Glx.Enums.GLXAttribute.GREEN_SIZE); + visualAttributes.Add((int)mode.Color.Green); + visualAttributes.Add((int)Glx.Enums.GLXAttribute.BLUE_SIZE); + visualAttributes.Add((int)mode.Color.Blue); + visualAttributes.Add((int)Glx.Enums.GLXAttribute.ALPHA_SIZE); + visualAttributes.Add((int)mode.Color.Alpha); + visualAttributes.Add((int)Glx.Enums.GLXAttribute.DEPTH_SIZE); + visualAttributes.Add((int)mode.DepthBits); + visualAttributes.Add((int)Glx.Enums.GLXAttribute.DOUBLEBUFFER); + visualAttributes.Add((int)0); + } + visual = Glx.ChooseVisual(windowInfo.Display, windowInfo.Screen, visualAttributes.ToArray()); if (visual == IntPtr.Zero) { @@ -104,12 +110,6 @@ namespace OpenTK.Platform.X11 windowInfo.VisualInfo = (VisualInfo)Marshal.PtrToStructure(visual, typeof(VisualInfo)); Debug.Print("Prepared visual: {0}", windowInfo.VisualInfo.ToString()); } - //} - //catch (Exception e) - //{ - // Debug.Print(e.ToString()); - // throw; - //} } #endregion diff --git a/Source/OpenTK/Platform/X11/X11GLControl.cs b/Source/OpenTK/Platform/X11/X11GLControl.cs index d7ac8577..d2f8ff8d 100644 --- a/Source/OpenTK/Platform/X11/X11GLControl.cs +++ b/Source/OpenTK/Platform/X11/X11GLControl.cs @@ -16,7 +16,7 @@ namespace OpenTK.Platform.X11 sealed class X11GLControl : IGLControl { WindowInfo info = new WindowInfo(); - DisplayMode mode; + //DisplayMode mode; private Type xplatui; X11GLContext glContext; @@ -25,25 +25,23 @@ namespace OpenTK.Platform.X11 #region --- Contructors --- - public X11GLControl(UserControl c, DisplayMode mode) + public X11GLControl(UserControl c) { Debug.WriteLine("Creating opengl control (X11GLControl driver)"); Debug.Indent(); + Utilities.ThrowOnX11Error = true; if (c == null/* || c.TopLevelControl == null*/) { throw new ArgumentException("UserControl c may not be null."); } - this.mode = mode;//new DisplayMode(mode); - glContext = new X11GLContext(mode); + //this.mode = mode; + glContext = new X11GLContext(null); c.HandleCreated += new EventHandler(c_HandleCreated); c.HandleDestroyed += new EventHandler(c_HandleDestroyed); - //c.ParentChanged += new EventHandler(c_ParentChanged); - //c.Load += new EventHandler(c_Load); - //Debug.Print("GLControl events hooked to X11GLControl."); xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms"); Debug.Write("System.Windows.Forms.XplatUIX11: "); @@ -61,42 +59,18 @@ namespace OpenTK.Platform.X11 Debug.Print("Display: {0}, Screen: {1}, Root Window: {2}, GLControl: {3}", info.Display, info.Screen, info.RootWindow, info.Handle); - + glContext.PrepareContext(info); info.VisualInfo = glContext.windowInfo.VisualInfo; + + Debug.Print("Setting XplatUIX11.CustomVisual"); xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) .SetValue(null, info.VisualInfo.visual); + Debug.Print("Setting XplatUIX11.CustomColormap"); xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) .SetValue(null, API.CreateColormap(info.Display, info.RootWindow, info.VisualInfo.visual, 0)); - - c.Visible = true; - glContext.windowInfo.Handle = info.Handle = c.Handle; } - - //Debug.Print("Parent: {0}", c.ParentForm.Handle); - //API.MapRaised(info.Display, info.Handle); - //API.MapRaised(info.Display, c.ParentForm.Handle); - - //OpenTK.OpenGL.GL.Imports.Flush(); - - /* - // Wait until the GLControl is mapped. - XEvent ev = new XEvent(); - API.IfEvent(info.Display, ref ev, - delegate(IntPtr display, ref XEvent @event, IntPtr arg) - { - Debug.Print("Checking event: {0}", @event.type); - if (@event.type == XEventName.MapNotify) - { - Debug.Print("Map event for window: {0}", @event.MapEvent.window); - } - return (@event.type == XEventName.MapNotify) && (@event.MapEvent.window == arg); - }, - info.Handle); - */ - //glContext.MakeCurrent(); - //OpenTK.OpenGL.GL.LoadAll(); Debug.Unindent(); } @@ -121,13 +95,6 @@ namespace OpenTK.Platform.X11 finally { Debug.Unindent(); - /* - Debug.WriteLine(String.Format("Mapping control {0} to parent {1}", c.Handle, c.Handle)); - API.MapRaised(info.Display, c.Handle); - - Context.MakeCurrent(); - OpenTK.OpenGL.GL.LoadAll(); - */ } } @@ -137,48 +104,7 @@ namespace OpenTK.Platform.X11 glContext.Dispose(); } - void c_ParentChanged(object sender, EventArgs e) - { - Debug.Print("Mapping X11GLControl."); - Debug.Indent(); - - Control c = sender as Control; - Debug.Print("TopLevel control is {0}", - c.TopLevelControl != null ? c.TopLevelControl.ToString() : "not available"); - - if (c.TopLevelControl == null) - { - throw new ApplicationException("Problem: GLControl does not have a parent, aborting."); - } - else - { - info.TopLevelWindow = c.TopLevelControl.Handle; - } - - Debug.WriteLine(String.Format("Mapping GLControl {0} to window {1}", info.Handle, info.TopLevelWindow)); - //API.MapRaised(info.Display, info.TopLevelWindow); - /* - // Wait until the GLControl is mapped. - XEvent ev = new XEvent(); - API.IfEvent(info.Display, ref ev, - delegate(IntPtr display, ref XEvent @event, IntPtr arg) - { - //Debug.Print("Checking event: {0}", @event.type); - return (@event.type == XEventName.MapNotify) && (@event.MapEvent.window == arg); - }, - info.Handle); - - glContext.MakeCurrent(); - OpenTK.OpenGL.GL.LoadAll();*/ - Debug.Unindent(); - } - - void c_Load(object sender, EventArgs e) - { - Debug.Print("GLControl loaded, will now try to make context current and load all GL functions."); - Context.MakeCurrent(); - OpenTK.OpenGL.GL.LoadAll(); - } + #region private IntPtr FindColormap() /// /// Finds a colormap suitable for use with the GLControl. @@ -201,6 +127,8 @@ namespace OpenTK.Platform.X11 #endregion + #endregion + #region --- IGLControl Members --- public event CreateEvent Create; diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs index d04322c7..783059f4 100644 --- a/Source/OpenTK/Platform/X11/X11GLNative.cs +++ b/Source/OpenTK/Platform/X11/X11GLNative.cs @@ -53,14 +53,8 @@ namespace OpenTK.Platform.X11 { Debug.Print("Native window driver: {0}", this.ToString()); window = new WindowInfo(); - Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms"); - if (xplatui != null) - { - FieldInfo f = xplatui.GetField("ErrorExceptions", - System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic); - if (f != null) - f.SetValue(null, true); - } + + Utilities.ThrowOnX11Error = true; } #endregion