#region --- License ---
/* Copyright (c) 2007 Stefanos Apostolopoulos
* See license.txt for license info
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Diagnostics;
namespace OpenTK.Platform.X11
{
sealed class X11GLControl : IGLControl
{
WindowInfo info = new WindowInfo();
//DisplayMode mode;
private Type xplatui;
IGLContext glContext;
private bool disposed;
private bool fullscreen;
#region --- Contructors ---
#region public X11GLControl(UserControl c)
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.");
}
c.HandleCreated += new EventHandler(c_HandleCreated);
c.HandleDestroyed += new EventHandler(c_HandleDestroyed);
xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
if (xplatui == null)
throw new ApplicationException("Could not get System.Windows.Forms.XplatUIX11 through reflection. Unsupported platform or Mono runtime version, aborting.");
info.Display = (IntPtr)xplatui.GetField("DisplayHandle",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
info.RootWindow = (IntPtr)xplatui.GetField("RootWindow",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
info.Screen = (int)xplatui.GetField("ScreenNo",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
Debug.Print("Data read from System.Windows.Forms.XplatUIX11: {0}", info.ToString());
//this.mode = mode;
glContext = new GLContext(null, info);
//glContext.PrepareContext(info);
info.VisualInfo = (glContext.Info as X11.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));
Debug.Unindent();
}
#endregion
#region void c_HandleCreated(object sender, EventArgs e)
void c_HandleCreated(object sender, EventArgs e)
{
UserControl c = (sender as UserControl);
Debug.Print("GLControl handle created, creating X11GLContext.");
Debug.Indent();
try
{
(glContext.Info as X11.WindowInfo).Handle = info.Handle = (sender as UserControl).Handle;
glContext.CreateContext(true, null);
glContext.MakeCurrent();
}
catch (ApplicationException expt)
{
Debug.Print(expt.ToString());
throw;
}
finally
{
Debug.Unindent();
}
}
#endregion
#region void c_HandleDestroyed(object sender, EventArgs e)
void c_HandleDestroyed(object sender, EventArgs e)
{
Debug.Print("X11GLControl handle destroyed, disposing X11GLContext.");
glContext.Dispose();
}
#endregion
#region private IntPtr FindColormap()
///
/// Finds a colormap suitable for use with the GLControl.
///
/// A pointer to the colormap
///
/// If the visual of the GLControl matches the default visual, the function returns
/// the default colormap (i.e. the colormap of the root window). Otherwise, it creates
/// a new, private colormap.
///
private IntPtr FindColormap()
{
if (info.VisualInfo.visual == Functions.XDefaultVisual(info.Display, info.Screen))
{
return Functions.XDefaultColormap(info.Display, info.Screen);
}
return API.CreateColormap(info.Display, info.RootWindow,
(glContext.Info as X11.WindowInfo).VisualInfo.visual, 0/*AllocNone*/);
}
#endregion
#endregion
#region --- IGLControl Members ---
public event CreateEvent Create;
private void OnCreate(object sender, EventArgs e)
{
if (this.Create != null)
this.Create(sender, e);
}
#region public bool IsIdle
public bool IsIdle
{
get
{
return API.Pending(info.Display) == 0;
}
}
#endregion
#region public bool Fullscreen
public bool Fullscreen
{
get
{
return fullscreen;
}
set
{
//throw new Exception("The method or operation is not implemented.");
fullscreen = false;
}
}
#endregion
#region public IGLContext Context
public IGLContext Context
{
get
{
return glContext;
}
}
#endregion
#endregion
#region --- IDisposable Members ---
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool manuallyCalled)
{
if (!disposed)
{
// Clean unmanaged resources:
// Nothing
if (manuallyCalled)
{
// Clean managed resources, too
glContext.Dispose();
}
}
disposed = true;
}
~X11GLControl()
{
this.Dispose(false);
}
#endregion
}
}