diff --git a/Source/Examples/Tutorial/T03_RotatingCube.cs b/Source/Examples/Tutorial/T03_RotatingCube.cs index 81f84aeb..27bba48c 100644 --- a/Source/Examples/Tutorial/T03_RotatingCube.cs +++ b/Source/Examples/Tutorial/T03_RotatingCube.cs @@ -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 diff --git a/Source/Examples/Tutorial/T07_DisplayLists_Cube.cs b/Source/Examples/Tutorial/T07_DisplayLists_Cube.cs index 5c1e50ef..f831be7e 100644 --- a/Source/Examples/Tutorial/T07_DisplayLists_Cube.cs +++ b/Source/Examples/Tutorial/T07_DisplayLists_Cube.cs @@ -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 diff --git a/Source/Examples/Tutorial/T08_VBO.cs b/Source/Examples/Tutorial/T08_VBO.cs index 721548a9..1438b307 100644 --- a/Source/Examples/Tutorial/T08_VBO.cs +++ b/Source/Examples/Tutorial/T08_VBO.cs @@ -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 diff --git a/Source/Examples/Tutorial/T10_GLSL_Cube.cs b/Source/Examples/Tutorial/T10_GLSL_Cube.cs index 0c68b77b..6d78c011 100644 --- a/Source/Examples/Tutorial/T10_GLSL_Cube.cs +++ b/Source/Examples/Tutorial/T10_GLSL_Cube.cs @@ -213,6 +213,7 @@ namespace Examples.Tutorial DrawCube(); Context.SwapBuffers(); + Thread.Sleep(0); } #endregion diff --git a/Source/Examples/WinForms/Cube.cs b/Source/Examples/WinForms/Cube.cs index 6791ee09..8ab04589 100644 --- a/Source/Examples/WinForms/Cube.cs +++ b/Source/Examples/WinForms/Cube.cs @@ -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 diff --git a/Source/OpenTK/GameWindow.cs b/Source/OpenTK/GameWindow.cs index 8160185d..26ff5c20 100644 --- a/Source/OpenTK/GameWindow.cs +++ b/Source/OpenTK/GameWindow.cs @@ -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) diff --git a/Source/OpenTK/Platform/X11/Structs.cs b/Source/OpenTK/Platform/X11/Structs.cs index 6ed282af..ca82dd8d 100644 --- a/Source/OpenTK/Platform/X11/Structs.cs +++ b/Source/OpenTK/Platform/X11/Structs.cs @@ -834,7 +834,7 @@ namespace OpenTK.Platform.X11 } [Flags] - internal enum EventMask// : long + internal enum EventMask : long { NoEventMask = 0, KeyPressMask = 1 << 0, diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index 04f62478..eb4361d3 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -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(); } diff --git a/Source/OpenTK/Platform/X11/X11GLControl.cs b/Source/OpenTK/Platform/X11/X11GLControl.cs index 0a2a8ce9..626383e0 100644 --- a/Source/OpenTK/Platform/X11/X11GLControl.cs +++ b/Source/OpenTK/Platform/X11/X11GLControl.cs @@ -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( diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs index 89906ed2..c56a916e 100644 --- a/Source/OpenTK/Platform/X11/X11GLNative.cs +++ b/Source/OpenTK/Platform/X11/X11GLNative.cs @@ -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) - - /// - /// Opens a new render window with the given DisplayMode. - /// - /// The DisplayMode of the render window. - /// - /// Creates the window visual and colormap. Associates the colormap/visual - /// with the window and raises the window on top of the window stack. - /// - /// Colormap creation is currently disabled. - /// - /// - 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 /// 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) + + /// + /// Opens a new render window with the given DisplayMode. + /// + /// The DisplayMode of the render window. + /// + /// Creates the window visual and colormap. Associates the colormap/visual + /// with the window and raises the window on top of the window stack. + /// + /// Colormap creation is currently disabled. + /// + /// + 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 - - } } diff --git a/Source/OpenTK/Platform/X11/X11Input.cs b/Source/OpenTK/Platform/X11/X11Input.cs index 9eb14753..2d90dbde 100644 --- a/Source/OpenTK/Platform/X11/X11Input.cs +++ b/Source/OpenTK/Platform/X11/X11Input.cs @@ -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();