Merge branch 'thefiddler-cursor' into develop
This commit is contained in:
commit
a07a61a003
18 changed files with 930 additions and 13 deletions
BIN
Source/Examples/Data/Textures/cursor.png
Normal file
BIN
Source/Examples/Data/Textures/cursor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
|
@ -146,6 +146,7 @@
|
|||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="OpenGL\1.x\TextRendering.cs" />
|
||||
<Compile Include="OpenTK\GameWindow\MouseCursorSimple.cs" />
|
||||
<Compile Include="OpenTK\Test\TestShaderUtf8Support.cs" />
|
||||
<Compile Include="SamplesTreeViewSorter.cs">
|
||||
<SubType>Code</SubType>
|
||||
|
@ -547,10 +548,14 @@
|
|||
</None>
|
||||
<None Include="Data\Audio\the_ring_that_fell.wav">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Data\Textures\cursor.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<EmbeddedResource Include="OpenGL\1.x\OpenGLDiagnostics.rtf" />
|
||||
<EmbeddedResource Include="OpenGL\1.x\Anaglyph.rtf" />
|
||||
<EmbeddedResource Include="OpenGL\1.x\TextRendering.rtf" />
|
||||
<EmbeddedResource Include="OpenTK\GameWindow\MouseCursorSimple.rtf" />
|
||||
<None Include="Resources\App.ico">
|
||||
</None>
|
||||
<None Include="..\OpenTK\OpenTK.dll.config">
|
||||
|
@ -643,4 +648,4 @@
|
|||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
171
Source/Examples/OpenTK/GameWindow/MouseCursorSimple.cs
Normal file
171
Source/Examples/OpenTK/GameWindow/MouseCursorSimple.cs
Normal file
|
@ -0,0 +1,171 @@
|
|||
// This code was written for the OpenTK library and has been released
|
||||
// to the Public Domain.
|
||||
// It is provided "as is" without express or implied warranty of any kind.
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace Examples.Tutorial
|
||||
{
|
||||
/// <summary>
|
||||
/// Demonstrates the MouseCursor class.
|
||||
/// </summary>
|
||||
[Example("MouseCursor Simple", ExampleCategory.OpenTK, "GameWindow", 1, Documentation = "MouseCursorSimple")]
|
||||
public class MouseCursorSimple : GameWindow
|
||||
{
|
||||
public MouseCursorSimple()
|
||||
: base(800, 600)
|
||||
{
|
||||
Keyboard.KeyDown += Keyboard_KeyDown;
|
||||
|
||||
Bitmap bitmap = new Bitmap("Data/Textures/cursor.png");
|
||||
|
||||
var rgba = new byte[bitmap.Width * bitmap.Height * 4];
|
||||
var data = bitmap.LockBits(
|
||||
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
|
||||
System.Drawing.Imaging.ImageLockMode.ReadOnly,
|
||||
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
for (int y = 0; y < bitmap.Height; ++y)
|
||||
{
|
||||
var offset = new IntPtr(data.Scan0.ToInt64() + (data.Stride * y));
|
||||
var stride = bitmap.Width * 4;
|
||||
System.Runtime.InteropServices.Marshal.Copy(
|
||||
offset, rgba, y * stride, stride);
|
||||
}
|
||||
|
||||
//this.Cursor = new OpenTK.MouseCursor(rgba, bitmap.Width, bitmap.Height, 0, 0);
|
||||
this.Cursor = MouseCursor.Default;
|
||||
}
|
||||
|
||||
#region Keyboard_KeyDown
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a key is pressed.
|
||||
/// </summary>
|
||||
/// <param name="sender">The KeyboardDevice which generated this event.</param>
|
||||
/// <param name="e">The key that was pressed.</param>
|
||||
void Keyboard_KeyDown(object sender, KeyboardKeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Escape)
|
||||
{
|
||||
this.Exit();
|
||||
}
|
||||
|
||||
if (e.Key == Key.Enter && e.Alt)
|
||||
{
|
||||
if (this.WindowState == WindowState.Fullscreen)
|
||||
this.WindowState = WindowState.Normal;
|
||||
else
|
||||
this.WindowState = WindowState.Fullscreen;
|
||||
}
|
||||
|
||||
if (e.Key == Key.Space)
|
||||
{
|
||||
if (Cursor == MouseCursor.Default)
|
||||
{
|
||||
Cursor = MouseCursor.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cursor = MouseCursor.Default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnLoad
|
||||
|
||||
/// <summary>
|
||||
/// Setup OpenGL and load resources here.
|
||||
/// </summary>
|
||||
/// <param name="e">Not used.</param>
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
GL.ClearColor(Color.MidnightBlue);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnResize
|
||||
|
||||
/// <summary>
|
||||
/// Respond to resize events here.
|
||||
/// </summary>
|
||||
/// <param name="e">Contains information on the new GameWindow size.</param>
|
||||
/// <remarks>There is no need to call the base implementation.</remarks>
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
GL.Viewport(0, 0, Width, Height);
|
||||
|
||||
GL.MatrixMode(MatrixMode.Projection);
|
||||
GL.LoadIdentity();
|
||||
GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 4.0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnUpdateFrame
|
||||
|
||||
/// <summary>
|
||||
/// Add your game logic here.
|
||||
/// </summary>
|
||||
/// <param name="e">Contains timing information.</param>
|
||||
/// <remarks>There is no need to call the base implementation.</remarks>
|
||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||
{
|
||||
// Nothing to do!
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region OnRenderFrame
|
||||
|
||||
/// <summary>
|
||||
/// Add your game rendering code here.
|
||||
/// </summary>
|
||||
/// <param name="e">Contains timing information.</param>
|
||||
/// <remarks>There is no need to call the base implementation.</remarks>
|
||||
protected override void OnRenderFrame(FrameEventArgs e)
|
||||
{
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
|
||||
GL.Begin(PrimitiveType.Triangles);
|
||||
|
||||
GL.Color3(Color.MidnightBlue);
|
||||
GL.Vertex2(-1.0f, 1.0f);
|
||||
GL.Color3(Color.SpringGreen);
|
||||
GL.Vertex2(0.0f, -1.0f);
|
||||
GL.Color3(Color.Ivory);
|
||||
GL.Vertex2(1.0f, 1.0f);
|
||||
|
||||
GL.End();
|
||||
|
||||
this.SwapBuffers();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public static void Main()
|
||||
|
||||
/// <summary>
|
||||
/// Entry point of this example.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
public static void Main()
|
||||
{
|
||||
using (MouseCursorSimple example = new MouseCursorSimple())
|
||||
{
|
||||
// Get the title and category of this example using reflection.
|
||||
Utilities.SetWindowTitle(example);
|
||||
example.Run(30.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
BIN
Source/Examples/OpenTK/GameWindow/MouseCursorSimple.rtf
Normal file
BIN
Source/Examples/OpenTK/GameWindow/MouseCursorSimple.rtf
Normal file
Binary file not shown.
|
@ -132,6 +132,12 @@ namespace OpenTK
|
|||
[Obsolete("Use OpenTK.Input.Mouse/Keybord/Joystick/GamePad instead.")]
|
||||
OpenTK.Input.IInputDriver InputDriver { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="OpenTK.MouseCursor"/> for this window.
|
||||
/// </summary>
|
||||
/// <value>The cursor.</value>
|
||||
MouseCursor Cursor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value, indicating whether the mouse cursor is visible.
|
||||
/// </summary>
|
||||
|
|
|
@ -211,12 +211,14 @@ namespace OpenTK.Input
|
|||
{
|
||||
args.Key = key;
|
||||
args.ScanCode = scancode;
|
||||
args.Modifiers = GetModifiers();
|
||||
KeyDown(this, args);
|
||||
}
|
||||
else if (!state && KeyUp != null)
|
||||
{
|
||||
args.Key = key;
|
||||
args.ScanCode = scancode;
|
||||
args.Modifiers = GetModifiers();
|
||||
KeyUp(this, args);
|
||||
}
|
||||
}
|
||||
|
|
101
Source/OpenTK/MouseCursor.cs
Normal file
101
Source/OpenTK/MouseCursor.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
#region License
|
||||
//
|
||||
// Cursor.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a predefined or custom mouse cursor.
|
||||
/// </summary>
|
||||
public sealed class MouseCursor : WindowIcon
|
||||
{
|
||||
static readonly MouseCursor default_cursor = new MouseCursor();
|
||||
static readonly MouseCursor empty_cursor = new MouseCursor(
|
||||
new byte[16 * 16 * 4], 16, 16, 0, 0);
|
||||
|
||||
byte[] rgba;
|
||||
int width;
|
||||
int height;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
MouseCursor()
|
||||
{
|
||||
}
|
||||
|
||||
// Todo: make public when byte-order issues are resolved
|
||||
internal MouseCursor(byte[] rgba, int width, int height, int x, int y)
|
||||
{
|
||||
if (rgba == null)
|
||||
throw new ArgumentNullException();
|
||||
if (width < 0 || width > 256 || height < 0 || height > 256)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
if (rgba.Length < width * height * 4)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
if (x < 0 || x >= width || y < 0 || y >= height)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
this.rgba = rgba;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
internal byte[] Rgba { get { return rgba; } }
|
||||
internal int Width { get { return width; } }
|
||||
internal int Height { get { return height; } }
|
||||
internal int X { get { return x; } }
|
||||
internal int Y { get { return y; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default mouse cursor for this platform.
|
||||
/// </summary>
|
||||
public static MouseCursor Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return default_cursor;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an empty (invisible) mouse cursor.
|
||||
/// </summary>
|
||||
public static MouseCursor Empty
|
||||
{
|
||||
get
|
||||
{
|
||||
return empty_cursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -259,6 +259,31 @@ namespace OpenTK
|
|||
|
||||
#endregion
|
||||
|
||||
#region Cursor
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="OpenTK.MouseCursor"/> for this window.
|
||||
/// </summary>
|
||||
public MouseCursor Cursor
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureUndisposed();
|
||||
return implementation.Cursor;
|
||||
}
|
||||
set
|
||||
{
|
||||
EnsureUndisposed();
|
||||
if (value == null)
|
||||
{
|
||||
value = MouseCursor.Empty;
|
||||
}
|
||||
implementation.Cursor = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Exists
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<ProjectType>Local</ProjectType>
|
||||
|
@ -759,6 +759,7 @@
|
|||
<Compile Include="Input\JoystickHat.cs" />
|
||||
<Compile Include="Input\HatPosition.cs" />
|
||||
<Compile Include="Input\JoystickHatState.cs" />
|
||||
<Compile Include="MouseCursor.cs" />
|
||||
<Compile Include="Input\KeyModifiers.cs" />
|
||||
<Compile Include="Platform\MacOS\CocoaContext.cs" />
|
||||
<Compile Include="Platform\MacOS\CocoaNativeWindow.cs" />
|
||||
|
@ -794,6 +795,7 @@
|
|||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Platform\MacOS\Carbon\Cgl.cs" />
|
||||
<Compile Include="WindowIcon.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
@ -823,5 +825,4 @@
|
|||
</Properties>
|
||||
</MonoDevelop>
|
||||
</ProjectExtensions>
|
||||
<ItemGroup />
|
||||
</Project>
|
|
@ -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(); }
|
||||
|
|
|
@ -112,6 +112,7 @@ namespace OpenTK.Platform.MacOS
|
|||
//static readonly IntPtr selIsInFullScreenMode = Selector.Get("isInFullScreenMode");
|
||||
//static readonly IntPtr selExitFullScreenModeWithOptions = Selector.Get("exitFullScreenModeWithOptions:");
|
||||
//static readonly IntPtr selEnterFullScreenModeWithOptions = Selector.Get("enterFullScreenMode:withOptions:");
|
||||
static readonly IntPtr selArrowCursor = Selector.Get("arrowCursor");
|
||||
|
||||
static readonly IntPtr NSDefaultRunLoopMode;
|
||||
static readonly IntPtr NSCursor;
|
||||
|
@ -142,8 +143,10 @@ namespace OpenTK.Platform.MacOS
|
|||
private int normalLevel;
|
||||
private bool shouldClose;
|
||||
private int suppressResize;
|
||||
private const float scrollFactor = 120.0f;
|
||||
private bool cursorInsideWindow = true;
|
||||
private MouseCursor selectedCursor = MouseCursor.Default; // user-selected cursor
|
||||
|
||||
private const float scrollFactor = 120.0f;
|
||||
private const bool exclusiveFullscreen = false;
|
||||
|
||||
public CocoaNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
||||
|
@ -412,11 +415,12 @@ namespace OpenTK.Platform.MacOS
|
|||
var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner);
|
||||
if (trackingAreaOwner == windowInfo.ViewHandle)
|
||||
{
|
||||
if (!cursorVisible)
|
||||
if (selectedCursor != MouseCursor.Default)
|
||||
{
|
||||
SetCursorVisible(false);
|
||||
SetCursor(selectedCursor);
|
||||
}
|
||||
|
||||
cursorInsideWindow = true;
|
||||
MouseEnter(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
@ -428,11 +432,12 @@ namespace OpenTK.Platform.MacOS
|
|||
var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner);
|
||||
if (trackingAreaOwner == windowInfo.ViewHandle)
|
||||
{
|
||||
if (!cursorVisible)
|
||||
if (selectedCursor != MouseCursor.Default)
|
||||
{
|
||||
SetCursorVisible(true);
|
||||
SetCursor(MouseCursor.Default);
|
||||
}
|
||||
|
||||
cursorInsideWindow = false;
|
||||
MouseLeave(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
@ -885,6 +890,27 @@ namespace OpenTK.Platform.MacOS
|
|||
}
|
||||
}
|
||||
|
||||
public MouseCursor Cursor
|
||||
{
|
||||
get
|
||||
{
|
||||
return selectedCursor;
|
||||
}
|
||||
set
|
||||
{
|
||||
// We only modify the cursor when it is
|
||||
// inside the window and visible.
|
||||
// If it is outside the window or invisible,
|
||||
// we store the selected cursor and change it
|
||||
// in the MouseEnter event.
|
||||
if (CursorVisible && cursorInsideWindow)
|
||||
{
|
||||
SetCursor(value);
|
||||
}
|
||||
selectedCursor = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CursorVisible
|
||||
{
|
||||
get { return cursorVisible; }
|
||||
|
@ -966,11 +992,26 @@ namespace OpenTK.Platform.MacOS
|
|||
|
||||
private void SetCursorVisible(bool visible)
|
||||
{
|
||||
// Problem: Unlike the PC version, you can move the mouse out of the window.
|
||||
// Perhaps use CG.WarpMouseCursorPosition to clamp mouse?
|
||||
Carbon.CG.AssociateMouseAndMouseCursorPosition(visible);
|
||||
Cocoa.SendVoid(NSCursor, visible ? selUnhide : selHide);
|
||||
}
|
||||
|
||||
private void SetCursor(MouseCursor cursor)
|
||||
{
|
||||
if (cursor == MouseCursor.Default)
|
||||
{
|
||||
Cocoa.SendVoid(NSCursor, selUnhide);
|
||||
}
|
||||
else if (cursor == MouseCursor.Empty)
|
||||
{
|
||||
Cocoa.SendVoid(NSCursor, selHide);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetMenuVisible(bool visible)
|
||||
{
|
||||
var options = (NSApplicationPresentationOptions)Cocoa.SendInt(NSApplication.Handle, selPresentationOptions);
|
||||
|
|
|
@ -33,6 +33,8 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace OpenTK.Platform.SDL2
|
||||
{
|
||||
using Surface = IntPtr;
|
||||
using Cursor = IntPtr;
|
||||
|
||||
partial class SDL
|
||||
{
|
||||
|
@ -77,6 +79,26 @@ namespace OpenTK.Platform.SDL2
|
|||
// strlen++;
|
||||
}
|
||||
|
||||
#region Cursor
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_CreateColorCursor", ExactSpelling = true)]
|
||||
public static extern Cursor CreateColorCursor(Surface surface, int hot_x, int hot_y);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_FreeCursor", ExactSpelling = true)]
|
||||
public static extern void FreeCursor(Cursor cursor);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetDefaultCursor", ExactSpelling = true)]
|
||||
public static extern IntPtr GetDefaultCursor();
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_SetCursor", ExactSpelling = true)]
|
||||
public static extern void SetCursor(Cursor cursor);
|
||||
|
||||
#endregion
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_AddEventWatch", ExactSpelling = true)]
|
||||
public static extern void AddEventWatch(EventFilter filter, IntPtr userdata);
|
||||
|
@ -220,6 +242,10 @@ namespace OpenTK.Platform.SDL2
|
|||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetModState", ExactSpelling = true)]
|
||||
public static extern Keymod GetModState();
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetMouseState", ExactSpelling = true)]
|
||||
public static extern ButtonFlags GetMouseState(out int hx, out int hy);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetNumDisplayModes", ExactSpelling = true)]
|
||||
public static extern int GetNumDisplayModes(int displayIndex);
|
||||
|
|
|
@ -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,86 @@ namespace OpenTK.Platform.SDL2
|
|||
public event EventHandler<EventArgs> MouseEnter = delegate { };
|
||||
public event EventHandler<EventArgs> 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),
|
||||
value.Width,
|
||||
value.Height,
|
||||
32,
|
||||
value.Width * 4,
|
||||
0xff000000,
|
||||
0x00ff0000,
|
||||
0x0000ff00,
|
||||
0x000000ff);
|
||||
|
||||
if (cursor_surface == IntPtr.Zero)
|
||||
{
|
||||
Debug.Print("[SDL2] Failed to create cursor surface. Error: {0}",
|
||||
SDL.GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
sdl_cursor = SDL.CreateColorCursor(cursor_surface, value.X, value.Y);
|
||||
if (sdl_cursor == IntPtr.Zero)
|
||||
{
|
||||
Debug.Print("[SDL2] Failed to create cursor. Error: {0}",
|
||||
SDL.GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -856,6 +856,98 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region CreateIconIndirect
|
||||
|
||||
/// <summary>
|
||||
/// Creates an icon or cursor from an IconInfo structure.
|
||||
/// </summary>
|
||||
/// <param name="iconInfo">
|
||||
/// A pointer to an IconInfo structure the function uses to create the
|
||||
/// icon or cursor.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is a handle to the icon
|
||||
/// or cursor that is created.
|
||||
///
|
||||
/// If the function fails, the return value is null. To get extended
|
||||
/// error information, call Marshal.GetLastWin32Error.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// The system copies the bitmaps in the IconInfo structure before
|
||||
/// creating the icon or cursor. Because the system may temporarily
|
||||
/// select the bitmaps in a device context, the hbmMask and hbmColor
|
||||
/// members of the IconInfo structure should not already be selected
|
||||
/// into a device context. The application must continue to manage the
|
||||
/// original bitmaps and delete them when they are no longer necessary.
|
||||
/// When you are finished using the icon, destroy it using the
|
||||
/// DestroyIcon function.
|
||||
/// </remarks>
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
public static extern HICON CreateIconIndirect(ref IconInfo iconInfo);
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetIconInfo
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves information about the specified icon or cursor.
|
||||
/// </summary>
|
||||
/// <param name="hIcon">A handle to the icon or cursor.</param>
|
||||
/// <param name="pIconInfo">
|
||||
/// A pointer to an IconInfo structure. The function fills in the
|
||||
/// structure's members.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is nonzero and the
|
||||
/// function fills in the members of the specified IconInfo structure.
|
||||
///
|
||||
/// If the function fails, the return value is zero. To get extended
|
||||
/// error information, call Marshal.GetLastWin32Error.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// GetIconInfo creates bitmaps for the hbmMask and hbmColor members
|
||||
/// of IconInfo. The calling application must manage these bitmaps and
|
||||
/// delete them when they are no longer necessary.
|
||||
/// </remarks>
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
public static extern BOOL GetIconInfo(HICON hIcon, out IconInfo pIconInfo);
|
||||
|
||||
#endregion
|
||||
|
||||
#region DestroyIcon
|
||||
|
||||
/// <summary>
|
||||
/// Destroys an icon and frees any memory the icon occupied.
|
||||
/// </summary>
|
||||
/// <param name="hIcon">
|
||||
/// A handle to the icon to be destroyed. The icon must not be in use.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is nonzero.
|
||||
///
|
||||
/// If the function fails, the return value is zero. To get extended
|
||||
/// error information, call Marshal.GetLastWin32Error.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// It is only necessary to call DestroyIcon for icons and cursors
|
||||
/// created with the following functions: CreateIconFromResourceEx
|
||||
/// (if called without the LR_SHARED flag), CreateIconIndirect, and
|
||||
/// CopyIcon. Do not use this function to destroy a shared icon. A
|
||||
/// shared icon is valid as long as the module from which it was loaded
|
||||
/// remains in memory. The following functions obtain a shared icon.
|
||||
///
|
||||
/// LoadIcon
|
||||
/// LoadImage (if you use the LR_SHARED flag)
|
||||
/// CopyImage (if you use the LR_COPYRETURNORG flag and the hImage parameter is a shared icon)
|
||||
/// CreateIconFromResource
|
||||
/// CreateIconFromResourceEx (if you use the LR_SHARED flag)
|
||||
/// </remarks>
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern BOOL DestroyIcon(HICON hIcon);
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern BOOL SetForegroundWindow(HWND hWnd);
|
||||
|
||||
|
@ -1043,6 +1135,53 @@ namespace OpenTK.Platform.Windows
|
|||
uint cbSize, MouseMovePoint* pointsIn,
|
||||
MouseMovePoint* pointsBufferOut, int nBufPoints, uint resolution);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the cursor shape.
|
||||
/// </summary>
|
||||
/// <param name="hCursor">
|
||||
/// A handle to the cursor. The cursor must have been created by the
|
||||
/// CreateCursor function or loaded by the LoadCursor or LoadImage
|
||||
/// function. If this parameter is IntPtr.Zero, the cursor is removed
|
||||
/// from the screen.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The return value is the handle to the previous cursor, if there was one.
|
||||
///
|
||||
/// If there was no previous cursor, the return value is null.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// The cursor is set only if the new cursor is different from the
|
||||
/// previous cursor; otherwise, the function returns immediately.
|
||||
///
|
||||
/// The cursor is a shared resource. A window should set the cursor
|
||||
/// shape only when the cursor is in its client area or when the window
|
||||
/// is capturing mouse input. In systems without a mouse, the window
|
||||
/// should restore the previous cursor before the cursor leaves the
|
||||
/// client area or before it relinquishes control to another window.
|
||||
///
|
||||
/// If your application must set the cursor while it is in a window,
|
||||
/// make sure the class cursor for the specified window's class is set
|
||||
/// to NULL. If the class cursor is not NULL, the system restores the
|
||||
/// class cursor each time the mouse is moved.
|
||||
///
|
||||
/// The cursor is not shown on the screen if the internal cursor
|
||||
/// display count is less than zero. This occurs if the application
|
||||
/// uses the ShowCursor function to hide the cursor more times than to
|
||||
/// show the cursor.
|
||||
/// </remarks>
|
||||
[DllImport("user32.dll")]
|
||||
public static extern HCURSOR SetCursor(HCURSOR hCursor);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a handle to the current cursor.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The return value is the handle to the current cursor. If there is
|
||||
/// no cursor, the return value is null.
|
||||
/// </returns>
|
||||
[DllImport("user32.dll")]
|
||||
public static extern HCURSOR GetCursor();
|
||||
|
||||
#region Async input
|
||||
|
||||
#region GetCursorPos
|
||||
|
@ -3007,6 +3146,57 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region IconInfo
|
||||
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Contains information about an icon or a cursor.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct IconInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies whether this structure defines an icon or a cursor. A
|
||||
/// value of TRUE specifies an icon; FALSE specifies a cursor
|
||||
/// </summary>
|
||||
public bool fIcon;
|
||||
|
||||
/// <summary>
|
||||
/// The x-coordinate of a cursor's hot spot. If this structure defines
|
||||
/// an icon, the hot spot is always in the center of the icon, and
|
||||
/// this member is ignored.
|
||||
/// </summary>
|
||||
public Int32 xHotspot;
|
||||
|
||||
/// <summary>
|
||||
/// The y-coordinate of a cursor's hot spot. If this structure defines
|
||||
/// an icon, the hot spot is always in the center of the icon, and
|
||||
/// this member is ignored.
|
||||
/// </summary>
|
||||
public Int32 yHotspot;
|
||||
|
||||
/// <summary>
|
||||
/// The icon bitmask bitmap. If this structure defines a black and
|
||||
/// white icon, this bitmask is formatted so that the upper half is
|
||||
/// the icon AND bitmask and the lower half is the icon XOR bitmask.
|
||||
/// Under this condition, the height should be an even multiple of
|
||||
/// two. If this structure defines a color icon, this mask only
|
||||
/// defines the AND bitmask of the icon.
|
||||
/// </summary>
|
||||
public IntPtr hbmMask;
|
||||
|
||||
/// <summary>
|
||||
/// A handle to the icon color bitmap. This member can be optional if
|
||||
/// this structure defines a black and white icon. The AND bitmask of
|
||||
/// hbmMask is applied with the SRCAND flag to the destination;
|
||||
/// subsequently, the color bitmap is applied (using XOR) to the
|
||||
/// destination by using the SRCINVERT flag.
|
||||
/// </summary>
|
||||
public IntPtr hbmColor;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Enums ---
|
||||
|
|
|
@ -101,6 +101,8 @@ namespace OpenTK.Platform.Windows
|
|||
KeyboardKeyEventArgs key_up = new KeyboardKeyEventArgs();
|
||||
KeyPressEventArgs key_press = new KeyPressEventArgs((char)0);
|
||||
|
||||
MouseCursor cursor = MouseCursor.Default;
|
||||
IntPtr curson_handle = IntPtr.Zero;
|
||||
int cursor_visible_count = 0;
|
||||
|
||||
static readonly object SyncRoot = new object();
|
||||
|
@ -386,6 +388,17 @@ namespace OpenTK.Platform.Windows
|
|||
}
|
||||
}
|
||||
|
||||
private IntPtr? HandleSetCursor(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
if (cursor != MouseCursor.Default)
|
||||
{
|
||||
Functions.SetCursor(curson_handle);
|
||||
return new IntPtr(1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void HandleChar(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
char c;
|
||||
|
@ -653,6 +666,8 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
IntPtr? result = null;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
#region Size / Move / Style events
|
||||
|
@ -686,6 +701,10 @@ namespace OpenTK.Platform.Windows
|
|||
HandleSize(handle, message, wParam, lParam);
|
||||
break;
|
||||
|
||||
case WindowMessage.SETCURSOR:
|
||||
result = HandleSetCursor(handle, message, wParam, lParam);
|
||||
break;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Input events
|
||||
|
@ -772,7 +791,14 @@ namespace OpenTK.Platform.Windows
|
|||
#endregion
|
||||
}
|
||||
|
||||
return Functions.DefWindowProc(handle, message, wParam, lParam);
|
||||
if (result.HasValue)
|
||||
{
|
||||
return result.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Functions.DefWindowProc(handle, message, wParam, lParam);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnableMouseTracking()
|
||||
|
@ -1164,7 +1190,78 @@ namespace OpenTK.Platform.Windows
|
|||
public bool Exists { get { return exists; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Cursor
|
||||
|
||||
public MouseCursor Cursor
|
||||
{
|
||||
get
|
||||
{
|
||||
return cursor;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != cursor)
|
||||
{
|
||||
bool destoryOld = cursor != MouseCursor.Default;
|
||||
IntPtr oldCursor = IntPtr.Zero;
|
||||
|
||||
if (value == MouseCursor.Default)
|
||||
{
|
||||
oldCursor = Functions.SetCursor(Functions.LoadCursor(CursorName.Arrow));
|
||||
cursor = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var stride = value.Width *
|
||||
(Bitmap.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format32bppArgb) / 8);
|
||||
|
||||
Bitmap bmp;
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pixels = value.Rgba)
|
||||
{
|
||||
bmp = new Bitmap(value.Width, value.Height, stride,
|
||||
System.Drawing.Imaging.PixelFormat.Format32bppArgb,
|
||||
new IntPtr(pixels));
|
||||
}
|
||||
}
|
||||
using (bmp)
|
||||
{
|
||||
var iconInfo = new IconInfo();
|
||||
var bmpIcon = bmp.GetHicon();
|
||||
var success = Functions.GetIconInfo(bmpIcon, out iconInfo);
|
||||
|
||||
if (success)
|
||||
{
|
||||
iconInfo.xHotspot = value.X;
|
||||
iconInfo.yHotspot = value.Y;
|
||||
iconInfo.fIcon = false;
|
||||
|
||||
var icon = Functions.CreateIconIndirect(ref iconInfo);
|
||||
|
||||
if (icon != IntPtr.Zero)
|
||||
{
|
||||
// Currently using a custom cursor so destroy it
|
||||
// once replaced
|
||||
cursor = value;
|
||||
curson_handle = icon;
|
||||
oldCursor = Functions.SetCursor(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (destoryOld && oldCursor != IntPtr.Zero)
|
||||
{
|
||||
Functions.DestroyIcon(oldCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CursorVisible
|
||||
|
||||
public bool CursorVisible
|
||||
|
|
|
@ -38,6 +38,11 @@ namespace OpenTK.Platform.X11
|
|||
using Display = System.IntPtr;
|
||||
using XPointer = System.IntPtr;
|
||||
|
||||
using XcursorBool = System.Int32;
|
||||
using XcursorUInt = System.UInt32;
|
||||
using XcursorDim = System.UInt32;
|
||||
using XcursorPixel = System.UInt32;
|
||||
|
||||
// Randr and Xrandr
|
||||
using Bool = System.Boolean;
|
||||
using XRRScreenConfiguration = System.IntPtr; // opaque datatype
|
||||
|
@ -579,6 +584,47 @@ XF86VidModeGetGammaRampSize(
|
|||
|
||||
#region X11 Structures
|
||||
|
||||
#region Xcursor
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
unsafe struct XcursorImage
|
||||
{
|
||||
public XcursorUInt version;
|
||||
public XcursorDim size;
|
||||
public XcursorDim width;
|
||||
public XcursorDim height;
|
||||
public XcursorDim xhot;
|
||||
public XcursorDim yhot;
|
||||
public XcursorUInt delay;
|
||||
public XcursorPixel* pixels;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
unsafe struct XcursorImages
|
||||
{
|
||||
public int nimage;
|
||||
public XcursorImage **images;
|
||||
public char *name;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
unsafe struct XcursorCursors
|
||||
{
|
||||
public Display dpy;
|
||||
public int refcount;
|
||||
public int ncursor;
|
||||
public Cursor *cursors;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
unsafe struct XcursorAnimate
|
||||
{
|
||||
public XcursorCursors *cursors;
|
||||
public int sequence;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal class XVisualInfo
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
|
@ -1388,6 +1434,7 @@ XF86VidModeGetGammaRampSize(
|
|||
internal static partial class Functions
|
||||
{
|
||||
internal const string X11Library = "libX11";
|
||||
internal const string XcursorLibrary = "libXcursor.so.1";
|
||||
|
||||
#region XCreateWindow
|
||||
|
||||
|
@ -1434,6 +1481,19 @@ XF86VidModeGetGammaRampSize(
|
|||
|
||||
#endregion
|
||||
|
||||
#region Xcursor
|
||||
|
||||
[DllImport(XcursorLibrary)]
|
||||
internal static unsafe extern XcursorImage* XcursorImageCreate(int width, int height);
|
||||
|
||||
[DllImport(XcursorLibrary)]
|
||||
internal static unsafe extern void XcursorImageDestroy(XcursorImage* image);
|
||||
|
||||
[DllImport(XcursorLibrary)]
|
||||
internal static unsafe extern Cursor XcursorImageLoadCursor(Display dpy, XcursorImage* image);
|
||||
|
||||
#endregion
|
||||
|
||||
#region XQueryKeymap
|
||||
|
||||
/*
|
||||
|
|
|
@ -115,6 +115,9 @@ namespace OpenTK.Platform.X11
|
|||
bool isExiting;
|
||||
|
||||
bool _decorations_hidden = false;
|
||||
|
||||
MouseCursor cursor = MouseCursor.Default;
|
||||
IntPtr cursorHandle;
|
||||
bool cursor_visible = true;
|
||||
int mouse_rel_x, mouse_rel_y;
|
||||
|
||||
|
@ -1460,6 +1463,48 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
#endregion
|
||||
|
||||
#region Cursor
|
||||
|
||||
public MouseCursor Cursor
|
||||
{
|
||||
get
|
||||
{
|
||||
return cursor;
|
||||
}
|
||||
set
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
using (new XLock(window.Display))
|
||||
{
|
||||
if (value == MouseCursor.Default)
|
||||
{
|
||||
Functions.XUndefineCursor(window.Display, window.Handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed(byte* pixels = value.Rgba)
|
||||
{
|
||||
var xcursorimage = Functions.XcursorImageCreate(value.Width, value.Height);
|
||||
xcursorimage->xhot = (uint)value.X;
|
||||
xcursorimage->yhot = (uint)value.Y;
|
||||
xcursorimage->pixels = (uint*)pixels;
|
||||
xcursorimage->delay = 0;
|
||||
cursorHandle = Functions.XcursorImageLoadCursor(window.Display, xcursorimage);
|
||||
Functions.XDefineCursor(window.Display, window.Handle, cursorHandle);
|
||||
Functions.XcursorImageDestroy(xcursorimage);
|
||||
}
|
||||
}
|
||||
cursor = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CursorVisible
|
||||
|
||||
public bool CursorVisible
|
||||
{
|
||||
get { return cursor_visible; }
|
||||
|
@ -1469,7 +1514,7 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
using (new XLock(window.Display))
|
||||
{
|
||||
Functions.XUndefineCursor(window.Display, window.Handle);
|
||||
Functions.XDefineCursor(window.Display, window.Handle, cursorHandle);
|
||||
cursor_visible = true;
|
||||
}
|
||||
}
|
||||
|
@ -1486,6 +1531,8 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- INativeGLWindow Members ---
|
||||
|
||||
#region public IInputDriver InputDriver
|
||||
|
@ -1704,6 +1751,10 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
using (new XLock(window.Display))
|
||||
{
|
||||
if(cursorHandle != IntPtr.Zero)
|
||||
{
|
||||
Functions.XFreeCursor(window.Display, cursorHandle);
|
||||
}
|
||||
Functions.XFreeCursor(window.Display, EmptyCursor);
|
||||
Functions.XDestroyWindow(window.Display, window.Handle);
|
||||
}
|
||||
|
|
45
Source/OpenTK/WindowIcon.cs
Normal file
45
Source/OpenTK/WindowIcon.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
#region License
|
||||
//
|
||||
// WindowIcon.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores a window icon. A window icon is defined
|
||||
/// as a 2-dimensional buffer of RGBA values.
|
||||
/// </summary>
|
||||
public class WindowIcon
|
||||
{
|
||||
internal protected WindowIcon()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue