Opentk/Source/OpenTK/Platform/X11/X11GLControl.cs
2007-08-07 17:24:03 +00:00

215 lines
6.1 KiB
C#

#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();
private Type xplatui;
X11GLContext glContext;
private bool quit;
private bool disposed;
private bool fullscreen;
#region --- Contructors ---
public X11GLControl(UserControl c, int width, int height, bool fullscreen)
{
Trace.WriteLine("Creating opengl control (X11GLControl driver)");
Trace.Indent();
c.ParentChanged += new EventHandler(c_ParentChanged);
if (c.ParentForm != null)
throw new Exception("I was stupid!");
if (c == null/* || c.TopLevelControl == null*/)
{
throw new Exception("Attempted to bind to non-existent control.");
}
info.Handle = c.Handle;
Trace.WriteLine(
String.Format(
"Binding to control: {0}",
String.IsNullOrEmpty(c.Name) ? c.Text : c.Name
)
);
xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
Trace.WriteLine("Acquired System.Windows.Forms.XplatUIX11 type.");
if (xplatui != null)
{
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);
Trace.WriteLine(
String.Format(
"Screen: {0}, Display: {1}, Root Window: {2}, Control: {3}",
info.Screen,
info.Display,
info.RootWindow,
info.Handle
)
);
glContext = new X11GLContext(info,
new DisplayMode(width, height, new ColorDepth(24), 16, 0, 0, 2, false, false, false, 0.0f)
);
glContext.CreateVisual();
xplatui.GetField(
"CustomVisual",
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.NonPublic).SetValue(
null,
glContext.XVisual
);
xplatui.GetField(
"CustomColormap",
System.Reflection.BindingFlags.Static |
System.Reflection.BindingFlags.NonPublic).SetValue(
null,
glContext.XColormap
);
glContext.CreateContext(null, true);
}
}
void c_ParentChanged(object sender, EventArgs e)
{
UserControl c = sender as UserControl;
Trace.WriteLine(
String.Format(
"TopLevel control is {0}",
c.TopLevelControl != null ? c.TopLevelControl.ToString() : "not available"
)
);
if (c.TopLevelControl == null)
{
info.TopLevelWindow = c.Handle;
throw new Exception("GLControl does not have a parent.");
}
else
{
info.TopLevelWindow = c.TopLevelControl.Handle;
}
Trace.WriteLine(String.Format("Mapping window to top level: {0}", info.TopLevelWindow));
API.MapRaised(info.Display, info.TopLevelWindow);
Trace.Unindent();
}
#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
}
}