From dd55cea48975f2aef20d326f75f5dd593a7c6072 Mon Sep 17 00:00:00 2001 From: thefiddler Date: Tue, 18 Feb 2014 16:44:28 +0100 Subject: [PATCH] [All] Initial implementation of INativeWindow.Cursor property Affects issue #9 --- Source/OpenTK/INativeWindow.cs | 6 ++ Source/OpenTK/NativeWindow.cs | 24 ++++++ .../OpenTK/Platform/MacOS/CarbonGLNative.cs | 14 ++++ .../OpenTK/Platform/SDL2/Sdl2NativeWindow.cs | 74 +++++++++++++++++++ Source/OpenTK/Platform/Windows/WinGLNative.cs | 19 ++++- Source/OpenTK/Platform/X11/X11GLNative.cs | 22 ++++++ 6 files changed, 158 insertions(+), 1 deletion(-) diff --git a/Source/OpenTK/INativeWindow.cs b/Source/OpenTK/INativeWindow.cs index b1df51fa..5cad3d6b 100644 --- a/Source/OpenTK/INativeWindow.cs +++ b/Source/OpenTK/INativeWindow.cs @@ -132,6 +132,12 @@ namespace OpenTK [Obsolete("Use OpenTK.Input.Mouse/Keybord/Joystick/GamePad instead.")] OpenTK.Input.IInputDriver InputDriver { get; } + /// + /// Gets or sets the for this window. + /// + /// The cursor. + MouseCursor Cursor { get; set; } + /// /// Gets or sets a value, indicating whether the mouse cursor is visible. /// diff --git a/Source/OpenTK/NativeWindow.cs b/Source/OpenTK/NativeWindow.cs index 28c51019..81af9e58 100644 --- a/Source/OpenTK/NativeWindow.cs +++ b/Source/OpenTK/NativeWindow.cs @@ -259,6 +259,30 @@ namespace OpenTK #endregion + #region Cursor + + /// + /// Gets or sets the for this window. + /// + public MouseCursor Cursor + { + get + { + EnsureUndisposed(); + return implementation.Cursor; + } + set + { + EnsureUndisposed(); + if (value == null) + throw new ArgumentNullException(); + + implementation.Cursor = value; + } + } + + #endregion + #region Exists /// diff --git a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs index c1334e2e..97063e5d 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonGLNative.cs @@ -83,6 +83,8 @@ namespace OpenTK.Platform.MacOS float mouse_rel_x; float mouse_rel_y; + MouseCursor cursor = MouseCursor.Default; + #endregion #region AGL Device Hack @@ -935,6 +937,18 @@ namespace OpenTK.Platform.MacOS } } + public MouseCursor Cursor + { + get + { + return cursor; + } + set + { + Debug.Print("[Warning] CarbonGLNative.Cursor property not implemented"); + } + } + public bool CursorVisible { get { return CG.CursorIsVisible(); } diff --git a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs index e90f8d8b..25760b5f 100644 --- a/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs +++ b/Source/OpenTK/Platform/SDL2/Sdl2NativeWindow.cs @@ -58,6 +58,8 @@ namespace OpenTK.Platform.SDL2 WindowState previous_window_state = WindowState.Normal; WindowBorder window_border = WindowBorder.Resizable; Icon icon; + MouseCursor cursor = MouseCursor.Default; + IntPtr sdl_cursor = IntPtr.Zero; string window_title; // Used in KeyPress event to decode SDL UTF8 text strings @@ -458,6 +460,78 @@ namespace OpenTK.Platform.SDL2 public event EventHandler MouseEnter = delegate { }; public event EventHandler MouseLeave = delegate { }; + public MouseCursor Cursor + { + get + { + return cursor; + } + set + { + lock (sync) + { + if (value != MouseCursor.Default) + { + // Free the previous cursor, + // if one has been set. + if (sdl_cursor != IntPtr.Zero) + { + SDL.FreeCursor(sdl_cursor); + sdl_cursor = IntPtr.Zero; + cursor = MouseCursor.Default; + } + + // Set the new cursor + if (value == MouseCursor.Default) + { + // Reset to default cursor + SDL.SetCursor(SDL.GetDefaultCursor()); + } + else + { + // Create and set a new cursor using + // the rgba values supplied by the user + unsafe + { + fixed (byte* pixels = value.Rgba) + { + IntPtr cursor_surface = + SDL.CreateRGBSurfaceFrom( + new IntPtr(pixels), + cursor.Width, + cursor.Height, + 32, + cursor.Width * 4, + 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff); + + sdl_cursor = SDL.CreateColorCursor( + cursor_surface, + cursor.Width, + cursor.Height, + cursor.X, + cursor.Y); + + if (sdl_cursor != IntPtr.Zero) + { + SDL.SetCursor(sdl_cursor); + cursor = value; + } + + if (cursor_surface != IntPtr.Zero) + { + SDL.FreeSurface(cursor_surface); + } + } + } + } + } + } + } + } + public void Close() { lock (sync) diff --git a/Source/OpenTK/Platform/Windows/WinGLNative.cs b/Source/OpenTK/Platform/Windows/WinGLNative.cs index c12cae77..94ca0c6e 100644 --- a/Source/OpenTK/Platform/Windows/WinGLNative.cs +++ b/Source/OpenTK/Platform/Windows/WinGLNative.cs @@ -101,6 +101,7 @@ namespace OpenTK.Platform.Windows KeyboardKeyEventArgs key_up = new KeyboardKeyEventArgs(); KeyPressEventArgs key_press = new KeyPressEventArgs((char)0); + MouseCursor cursor = MouseCursor.Default; int cursor_visible_count = 0; static readonly object SyncRoot = new object(); @@ -1164,7 +1165,23 @@ namespace OpenTK.Platform.Windows public bool Exists { get { return exists; } } #endregion - + + #region Cursor + + public MouseCursor Cursor + { + get + { + return cursor; + } + set + { + Debug.Print("[Warning] WinGLNative.Cursor property not implemented"); + } + } + + #endregion + #region CursorVisible public bool CursorVisible diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs index 5c32458a..ff16e251 100644 --- a/Source/OpenTK/Platform/X11/X11GLNative.cs +++ b/Source/OpenTK/Platform/X11/X11GLNative.cs @@ -115,6 +115,8 @@ namespace OpenTK.Platform.X11 bool isExiting; bool _decorations_hidden = false; + + MouseCursor cursor = MouseCursor.Default; bool cursor_visible = true; int mouse_rel_x, mouse_rel_y; @@ -1460,6 +1462,24 @@ namespace OpenTK.Platform.X11 #endregion + #region Cursor + + public MouseCursor Cursor + { + get + { + return cursor; + } + set + { + Debug.Print("[Warning] X11GLNative.Cursor property not implemented"); + } + } + + #endregion + + #region CursorVisible + public bool CursorVisible { get { return cursor_visible; } @@ -1486,6 +1506,8 @@ namespace OpenTK.Platform.X11 #endregion + #endregion + #region --- INativeGLWindow Members --- #region public IInputDriver InputDriver