Keyboard handling now plays well with normal event handling on X11.

One more issue to go: GLControl on X11 throws when calling MakeCurrent.
This commit is contained in:
the_fiddler 2007-08-06 12:13:50 +00:00
parent 6e9ac53c7f
commit c67859d7ca
11 changed files with 164 additions and 139 deletions

View file

@ -14,6 +14,7 @@ using OpenTK;
using OpenTK.OpenGL;
using OpenTK.Platform;
using Enums = OpenTK.OpenGL.GL.Enums;
using System.Threading;
#endregion
@ -124,6 +125,7 @@ namespace Examples.Tutorial
DrawCube();
Context.SwapBuffers();
Thread.Sleep(0);
}
#endregion

View file

@ -17,6 +17,7 @@ using System.Windows.Forms;
using OpenTK.OpenGL;
using Enums = OpenTK.OpenGL.GL.Enums;
using OpenTK;
using System.Threading;
#endregion --- Using Directives ---
@ -158,6 +159,7 @@ namespace Examples.Tutorial
Context.SwapBuffers();
Thread.Sleep(0);
}
#endregion

View file

@ -13,6 +13,7 @@ using System.Text;
using OpenTK;
using OpenTK.OpenGL;
using OpenTK.Platform;
using System.Threading;
#endregion
@ -177,6 +178,7 @@ namespace Examples.Tutorial
GL.BindBuffer(GL.Enums.VERSION_1_5.ELEMENT_ARRAY_BUFFER, 0);
Context.SwapBuffers();
Thread.Sleep(0);
}
#endregion

View file

@ -213,6 +213,7 @@ namespace Examples.Tutorial
DrawCube();
Context.SwapBuffers();
Thread.Sleep(0);
}
#endregion

View file

@ -17,6 +17,7 @@ using System.Windows.Forms;
using OpenTK.OpenGL;
using Enums = OpenTK.OpenGL.GL.Enums;
using OpenTK.Platform;
using System.Threading;
#endregion
@ -81,6 +82,7 @@ namespace Examples.WinForms
DrawCube();
glControl.Context.SwapBuffers();
Thread.Sleep(0);
}
#endregion

View file

@ -55,12 +55,14 @@ namespace OpenTK
glWindow.Resize += new ResizeEvent(glWindow_Resize);
glWindow.Create += new CreateEvent(glWindow_CreateInputDriver);
glWindow.Destroy += new DestroyEvent(glWindow_Destroy);
//glWindow.Destroy += new DestroyEvent(glWindow_Destroy);
}
void glWindow_Destroy(object sender, EventArgs e)
{
Debug.Print("GameWindow {0} notified of destruction.", this.isExiting.ToString());
this.isExiting = true;
glWindow.Destroy -= glWindow_Destroy;
}
void glWindow_CreateInputDriver(object sender, EventArgs e)

View file

@ -834,7 +834,7 @@ namespace OpenTK.Platform.X11
}
[Flags]
internal enum EventMask// : long
internal enum EventMask : long
{
NoEventMask = 0,
KeyPressMask = 1 << 0,

View file

@ -20,8 +20,6 @@ namespace OpenTK.Platform.X11
public sealed class X11GLContext : OpenTK.Platform.IGLContext
{
private IntPtr x11context;
private IntPtr display;
private int screenNo;
private DisplayMode mode;// = new DisplayMode();
internal WindowInfo windowInfo;
@ -42,6 +40,7 @@ namespace OpenTK.Platform.X11
internal X11GLContext()
{
this.windowInfo = new WindowInfo();
this.mode = new DisplayMode();
}

View file

@ -74,9 +74,10 @@ namespace OpenTK.Platform.X11
)
);
glContext = new X11GLContext(info, new DisplayMode(
width, height, new ColorDepth(24), 16, 0, 0, 2, false, false, false, 0.0f)
glContext = new X11GLContext(info,
new DisplayMode(width, height, new ColorDepth(24), 16, 0, 0, 2, false, false, false, 0.0f),
);
glContext.CreateVisual();
xplatui.GetField(

View file

@ -37,7 +37,7 @@ namespace OpenTK.Platform.X11
private XEvent e = new XEvent();
private bool disposed;
private bool created;
private bool exists;
#endregion
@ -56,121 +56,6 @@ namespace OpenTK.Platform.X11
#region --- INativeGLWindow Members ---
#region public void CreateWindow(DisplayMode mode)
/// <summary>
/// Opens a new render window with the given DisplayMode.
/// </summary>
/// <param name="mode">The DisplayMode of the render window.</param>
/// <remarks>
/// Creates the window visual and colormap. Associates the colormap/visual
/// with the window and raises the window on top of the window stack.
/// <para>
/// Colormap creation is currently disabled.
/// </para>
/// </remarks>
public void CreateWindow(DisplayMode mode)
{
if (created)
{
throw new ApplicationException("Render window already exists!");
}
else
{
Debug.Print("Creating native window with mode: {0}", mode.ToString());
Debug.Indent();
window.Display = API.OpenDisplay(null); // null == default display
if (window.Display == IntPtr.Zero)
{
throw new Exception("Could not open connection to X");
}
window.Screen = API.DefaultScreen(window.Display);
window.RootWindow = API.RootWindow(window.Display, window.Screen);
Debug.Print(
"Display: {0}, Screen {1}, Root window: {2}",
window.Display,
window.Screen,
window.RootWindow
);
glContext = new X11GLContext(window, mode);
window.VisualInfo = glContext.CreateVisual();
// Create a window on this display using the visual above
Debug.Write("Creating output window... ");
XSetWindowAttributes attributes = new XSetWindowAttributes();
attributes.colormap = glContext.colormap;
attributes.event_mask = (IntPtr)(EventMask.StructureNotifyMask | EventMask.ExposureMask);
SetWindowValuemask mask = SetWindowValuemask.ColorMap | SetWindowValuemask.EventMask;
window.Handle = Functions.XCreateWindow(window.Display, window.RootWindow,
0, 0, mode.Width, mode.Height, 0, glContext.XVisualInfo.depth,
(int)CreateWindowArgs.InputOutput, glContext.XVisualInfo.visual, (UIntPtr)mask,
ref attributes);
if (window.Handle == IntPtr.Zero)
{
throw new Exception("Could not create window.");
}
/*
// Set the window hints
XSizeHints hints = new XSizeHints();
hints.x = 0;
hints.y = 0;
hints.width = 640;
hints.height = 480;
hints.flags = (IntPtr)(XSizeHintsFlags.USSize | XSizeHintsFlags.USPosition);
Functions.XSetWMNormalHints(window.Display, window.Handle, ref hints);
XTextProperty text = new XTextProperty();
text.value = "OpenTK Game Window";
text.format = 8;
Functions.XSetWMName(window.Display, window.Handle, ref text);
Functions.XSetWMProperties(
display,
window,
name,
name,
0, // None
null,
0,
hints
);*/
Debug.Print("done! (id: {0})", window.Handle);
glContext.windowInfo.Handle = window.Handle;
glContext.CreateContext(null, true);
API.MapRaised(window.Display, window.Handle);
Debug.WriteLine("Mapped window.");
glContext.MakeCurrent();
Debug.WriteLine("Our shiny new context is now current - ready to rock 'n' roll!");
Debug.Unindent();
created = true;
}
}
#endregion
#region public void Exit()
public void Exit()
{
Debug.WriteLine("X11GLNative shutdown sequence initiated.");
quit = true;
Functions.XUnmapWindow(window.Display, window.Handle);
Functions.XDestroyWindow(window.Display, window.Handle);
}
#endregion
#region public void ProcessEvents()
public void ProcessEvents()
@ -178,10 +63,14 @@ namespace OpenTK.Platform.X11
// Process all pending events
while (true)
{
pending = Functions.XPending(window.Display);
//pending = Functions.XPending(window.Display);
pending = API.Pending(window.Display);
if (pending == 0)
{
//Debug.Print("No events pending on display {0}", window.Display);
return;
}
Functions.XNextEvent(window.Display, ref e);
@ -201,10 +90,11 @@ namespace OpenTK.Platform.X11
break;
case XEventName.DestroyNotify:
glContext.Dispose();
this.exists = false;
this.OnDestroy(EventArgs.Empty);
quit = true;
Debug.WriteLine("Window destroyed, shutting down.");
break;
Debug.Print("X11 window {0} destroyed.", e.DestroyWindowEvent.window);
return;
case XEventName.ConfigureNotify:
@ -242,7 +132,7 @@ namespace OpenTK.Platform.X11
/// </summary>
public bool Exists
{
get { return created; }
get { return exists; }
}
#endregion
@ -314,11 +204,110 @@ namespace OpenTK.Platform.X11
#endregion
public void DestroyWindow()
#region public void CreateWindow(DisplayMode mode)
/// <summary>
/// Opens a new render window with the given DisplayMode.
/// </summary>
/// <param name="mode">The DisplayMode of the render window.</param>
/// <remarks>
/// Creates the window visual and colormap. Associates the colormap/visual
/// with the window and raises the window on top of the window stack.
/// <para>
/// Colormap creation is currently disabled.
/// </para>
/// </remarks>
public void CreateWindow(DisplayMode mode)
{
throw new Exception("The method or operation is not implemented.");
if (exists)
{
throw new ApplicationException("Render window already exists!");
}
else
{
Debug.Print("Creating native window with mode: {0}", mode.ToString());
Debug.Indent();
window.Display = API.OpenDisplay(null); // null == default display
if (window.Display == IntPtr.Zero)
{
throw new Exception("Could not open connection to X");
}
window.Screen = API.DefaultScreen(window.Display);
window.RootWindow = API.RootWindow(window.Display, window.Screen);
Debug.Print(
"Display: {0}, Screen {1}, Root window: {2}",
window.Display,
window.Screen,
window.RootWindow
);
glContext = new X11GLContext(window, mode);
window.VisualInfo = glContext.CreateVisual();
// Create a window on this display using the visual above
Debug.Write("Creating output window... ");
XSetWindowAttributes attributes = new XSetWindowAttributes();
attributes.colormap = glContext.colormap;
attributes.event_mask = (IntPtr)(EventMask.StructureNotifyMask |
EventMask.SubstructureNotifyMask | EventMask.ExposureMask);
SetWindowValuemask mask = SetWindowValuemask.ColorMap | SetWindowValuemask.EventMask;
window.Handle = Functions.XCreateWindow(window.Display, window.RootWindow,
0, 0, mode.Width, mode.Height, 0, glContext.XVisualInfo.depth,
(int)CreateWindowArgs.InputOutput, glContext.XVisualInfo.visual, (UIntPtr)mask,
ref attributes);
if (window.Handle == IntPtr.Zero)
{
throw new Exception("Could not create window.");
}
/*
// Set the window hints
XSizeHints hints = new XSizeHints();
hints.x = 0;
hints.y = 0;
hints.width = 640;
hints.height = 480;
hints.flags = (IntPtr)(XSizeHintsFlags.USSize | XSizeHintsFlags.USPosition);
Functions.XSetWMNormalHints(window.Display, window.Handle, ref hints);
XTextProperty text = new XTextProperty();
text.value = "OpenTK Game Window";
text.format = 8;
Functions.XSetWMName(window.Display, window.Handle, ref text);
Functions.XSetWMProperties(
display,
window,
name,
name,
0, // None
null,
0,
hints
);*/
Debug.Print("done! (id: {0})", window.Handle);
glContext.windowInfo.Handle = window.Handle;
glContext.CreateContext(null, true);
API.MapRaised(window.Display, window.Handle);
Debug.WriteLine("Mapped window.");
glContext.MakeCurrent();
Debug.WriteLine("Our shiny new context is now current - ready to rock 'n' roll!");
Debug.Unindent();
exists = true;
}
}
#endregion
#region OnCreate
public event CreateEvent Create;
@ -334,15 +323,43 @@ namespace OpenTK.Platform.X11
#endregion
#region public void Exit()
public void Exit()
{
this.DestroyWindow();
}
#endregion
#region public void DestroyWindow()
public void DestroyWindow()
{
Debug.WriteLine("X11GLNative shutdown sequence initiated.");
// Functions.XUnmapWindow(window.Display, window.Handle);
Functions.XDestroyWindow(window.Display, window.Handle);
}
#endregion
#region OnDestroy
public void OnDestroy(EventArgs e)
{
throw new Exception("The method or operation is not implemented.");
Debug.Print("Destroy event fired from window: {0}", window.ToString());
if (this.Destroy != null)
{
this.Destroy(this, e);
}
}
public event DestroyEvent Destroy;
#endregion
#endregion
#region --- IResizable Members ---
#region public int Width
@ -433,7 +450,7 @@ namespace OpenTK.Platform.X11
{
if (!disposed)
{
if (window != null)
if (Exists)
Functions.XDestroyWindow(window.Display, window.Handle);
// Kills connection to the X-Server. We don't want that,
// 'cause it kills the ExampleLauncher too.
@ -454,7 +471,5 @@ namespace OpenTK.Platform.X11
}
#endregion
}
}

View file

@ -72,16 +72,15 @@ namespace OpenTK.Platform.X11
API.GrabKeyboard(window.Display, window.Handle, false, GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, 0);
Debug.WriteLine("done! (id: " + window + ")");
// Select input events to be reported here.
//API.SelectInput(window.Display, window.Parent.Handle,
// EventMask.KeyReleaseMask | EventMask.KeyPressMask);
keyboardDriver = new X11Keyboard(window);
*/
window = new WindowInfo(parent);
keyboardDriver = new X11Keyboard(parent);
API.SelectInput(parent.Display, parent.Handle,
// Todo: donparent's mask is now specified by hand, hard to keep in sync.
API.SelectInput(parent.Display, parent.Handle, EventMask.StructureNotifyMask |
EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
EventMask.KeyReleaseMask | EventMask.KeyPressMask);
Debug.Unindent();