Improved X11GLControl compatibility - now sets a safe DisplayMode.

Added utility that control's whether xplatui should throw exceptions on X11 errors.
This commit is contained in:
the_fiddler 2007-08-21 10:48:32 +00:00
parent 022b37e3cc
commit 0b5a0b4e1f
6 changed files with 101 additions and 137 deletions

View file

@ -25,7 +25,15 @@ namespace Examples.WinForms
{ {
public W01_First_Window() public W01_First_Window()
{ {
InitializeComponent(); try
{
InitializeComponent();
}
catch (Exception e)
{
System.Diagnostics.Trace.WriteLine("Exception during initialization, aborting: {0}", e.ToString());
return;
}
this.ShowDialog(); this.ShowDialog();
} }

View file

@ -92,23 +92,34 @@ namespace OpenTK
/// </summary> /// </summary>
public void CreateContext() public void CreateContext()
{ {
if (Environment.OSVersion.Platform == PlatformID.Win32NT || try
Environment.OSVersion.Platform == PlatformID.Win32Windows)
{ {
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 || catch (Exception e)
Environment.OSVersion.Platform == (PlatformID)128) // some older versions of Mono reported 128.
{ {
glControl = new OpenTK.Platform.X11.X11GLControl(this, new DisplayMode(Width, Height)); Debug.Print("Could not create GLControl, error: {0}", e.ToString());
} throw;
else
{
throw new PlatformNotSupportedException(
"Your operating system is not currently supported. We are sorry for the inconvenience."
);
} }
this.Visible = true;
OpenTK.OpenGL.GL.LoadAll(); OpenTK.OpenGL.GL.LoadAll();
this.OnResize(EventArgs.Empty); this.OnResize(EventArgs.Empty);
} }

View file

@ -166,5 +166,28 @@ namespace OpenTK.Platform
} }
#endregion #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);
}
}
}
} }
} }

View file

@ -20,16 +20,10 @@ namespace OpenTK.Platform.X11
public sealed class X11GLContext : OpenTK.Platform.IGLContext public sealed class X11GLContext : OpenTK.Platform.IGLContext
{ {
private IntPtr context; private IntPtr context;
private DisplayMode mode;// = new DisplayMode(); private DisplayMode mode;
internal WindowInfo windowInfo; internal WindowInfo windowInfo;
//private IntPtr desktopResolution = IntPtr.Zero; internal IntPtr visual;
//private int depthBits;
//private int stencilBits;
// These have to be used by the X11GLControl.
private IntPtr visual;
private bool disposed; private bool disposed;
@ -74,26 +68,38 @@ namespace OpenTK.Platform.X11
{ {
this.windowInfo = new WindowInfo(info); this.windowInfo = new WindowInfo(info);
Debug.Print("Preparing visual for DisplayMode: {0}", mode.ToString());
List<int> visualAttributes = new List<int>(); List<int> visualAttributes = new List<int>();
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()); visual = Glx.ChooseVisual(windowInfo.Display, windowInfo.Screen, visualAttributes.ToArray());
if (visual == IntPtr.Zero) if (visual == IntPtr.Zero)
{ {
@ -104,12 +110,6 @@ namespace OpenTK.Platform.X11
windowInfo.VisualInfo = (VisualInfo)Marshal.PtrToStructure(visual, typeof(VisualInfo)); windowInfo.VisualInfo = (VisualInfo)Marshal.PtrToStructure(visual, typeof(VisualInfo));
Debug.Print("Prepared visual: {0}", windowInfo.VisualInfo.ToString()); Debug.Print("Prepared visual: {0}", windowInfo.VisualInfo.ToString());
} }
//}
//catch (Exception e)
//{
// Debug.Print(e.ToString());
// throw;
//}
} }
#endregion #endregion

View file

@ -16,7 +16,7 @@ namespace OpenTK.Platform.X11
sealed class X11GLControl : IGLControl sealed class X11GLControl : IGLControl
{ {
WindowInfo info = new WindowInfo(); WindowInfo info = new WindowInfo();
DisplayMode mode; //DisplayMode mode;
private Type xplatui; private Type xplatui;
X11GLContext glContext; X11GLContext glContext;
@ -25,25 +25,23 @@ namespace OpenTK.Platform.X11
#region --- Contructors --- #region --- Contructors ---
public X11GLControl(UserControl c, DisplayMode mode) public X11GLControl(UserControl c)
{ {
Debug.WriteLine("Creating opengl control (X11GLControl driver)"); Debug.WriteLine("Creating opengl control (X11GLControl driver)");
Debug.Indent(); Debug.Indent();
Utilities.ThrowOnX11Error = true;
if (c == null/* || c.TopLevelControl == null*/) if (c == null/* || c.TopLevelControl == null*/)
{ {
throw new ArgumentException("UserControl c may not be null."); throw new ArgumentException("UserControl c may not be null.");
} }
this.mode = mode;//new DisplayMode(mode); //this.mode = mode;
glContext = new X11GLContext(mode); glContext = new X11GLContext(null);
c.HandleCreated += new EventHandler(c_HandleCreated); c.HandleCreated += new EventHandler(c_HandleCreated);
c.HandleDestroyed += new EventHandler(c_HandleDestroyed); 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"); xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
Debug.Write("System.Windows.Forms.XplatUIX11: "); 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}", Debug.Print("Display: {0}, Screen: {1}, Root Window: {2}, GLControl: {3}",
info.Display, info.Screen, info.RootWindow, info.Handle); info.Display, info.Screen, info.RootWindow, info.Handle);
glContext.PrepareContext(info); glContext.PrepareContext(info);
info.VisualInfo = glContext.windowInfo.VisualInfo; info.VisualInfo = glContext.windowInfo.VisualInfo;
Debug.Print("Setting XplatUIX11.CustomVisual");
xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, info.VisualInfo.visual); .SetValue(null, info.VisualInfo.visual);
Debug.Print("Setting XplatUIX11.CustomColormap");
xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic) xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
.SetValue(null, API.CreateColormap(info.Display, info.RootWindow, info.VisualInfo.visual, 0)); .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(); Debug.Unindent();
} }
@ -121,13 +95,6 @@ namespace OpenTK.Platform.X11
finally finally
{ {
Debug.Unindent(); 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(); glContext.Dispose();
} }
void c_ParentChanged(object sender, EventArgs e) #region private IntPtr FindColormap()
{
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();
}
/// <summary> /// <summary>
/// Finds a colormap suitable for use with the GLControl. /// Finds a colormap suitable for use with the GLControl.
@ -201,6 +127,8 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#endregion
#region --- IGLControl Members --- #region --- IGLControl Members ---
public event CreateEvent Create; public event CreateEvent Create;

View file

@ -53,14 +53,8 @@ namespace OpenTK.Platform.X11
{ {
Debug.Print("Native window driver: {0}", this.ToString()); Debug.Print("Native window driver: {0}", this.ToString());
window = new WindowInfo(); window = new WindowInfo();
Type xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
if (xplatui != null) Utilities.ThrowOnX11Error = true;
{
FieldInfo f = xplatui.GetField("ErrorExceptions",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
if (f != null)
f.SetValue(null, true);
}
} }
#endregion #endregion