mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-02-02 20:01:14 +00:00
Merge branch 'cursor' of https://github.com/thefiddler/opentk into thefiddler-cursor
This commit is contained in:
commit
4f9a2f78d6
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>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="OpenGL\1.x\TextRendering.cs" />
|
<Compile Include="OpenGL\1.x\TextRendering.cs" />
|
||||||
|
<Compile Include="OpenTK\GameWindow\MouseCursorSimple.cs" />
|
||||||
<Compile Include="OpenTK\Test\TestShaderUtf8Support.cs" />
|
<Compile Include="OpenTK\Test\TestShaderUtf8Support.cs" />
|
||||||
<Compile Include="SamplesTreeViewSorter.cs">
|
<Compile Include="SamplesTreeViewSorter.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
|
@ -547,10 +548,14 @@
|
||||||
</None>
|
</None>
|
||||||
<None Include="Data\Audio\the_ring_that_fell.wav">
|
<None Include="Data\Audio\the_ring_that_fell.wav">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Include="Data\Textures\cursor.png">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<EmbeddedResource Include="OpenGL\1.x\OpenGLDiagnostics.rtf" />
|
<EmbeddedResource Include="OpenGL\1.x\OpenGLDiagnostics.rtf" />
|
||||||
<EmbeddedResource Include="OpenGL\1.x\Anaglyph.rtf" />
|
<EmbeddedResource Include="OpenGL\1.x\Anaglyph.rtf" />
|
||||||
<EmbeddedResource Include="OpenGL\1.x\TextRendering.rtf" />
|
<EmbeddedResource Include="OpenGL\1.x\TextRendering.rtf" />
|
||||||
|
<EmbeddedResource Include="OpenTK\GameWindow\MouseCursorSimple.rtf" />
|
||||||
<None Include="Resources\App.ico">
|
<None Include="Resources\App.ico">
|
||||||
</None>
|
</None>
|
||||||
<None Include="..\OpenTK\OpenTK.dll.config">
|
<None Include="..\OpenTK\OpenTK.dll.config">
|
||||||
|
|
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.")]
|
[Obsolete("Use OpenTK.Input.Mouse/Keybord/Joystick/GamePad instead.")]
|
||||||
OpenTK.Input.IInputDriver InputDriver { get; }
|
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>
|
/// <summary>
|
||||||
/// Gets or sets a value, indicating whether the mouse cursor is visible.
|
/// Gets or sets a value, indicating whether the mouse cursor is visible.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -211,12 +211,14 @@ namespace OpenTK.Input
|
||||||
{
|
{
|
||||||
args.Key = key;
|
args.Key = key;
|
||||||
args.ScanCode = scancode;
|
args.ScanCode = scancode;
|
||||||
|
args.Modifiers = GetModifiers();
|
||||||
KeyDown(this, args);
|
KeyDown(this, args);
|
||||||
}
|
}
|
||||||
else if (!state && KeyUp != null)
|
else if (!state && KeyUp != null)
|
||||||
{
|
{
|
||||||
args.Key = key;
|
args.Key = key;
|
||||||
args.ScanCode = scancode;
|
args.ScanCode = scancode;
|
||||||
|
args.Modifiers = GetModifiers();
|
||||||
KeyUp(this, args);
|
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
|
#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
|
#region Exists
|
||||||
|
|
||||||
/// <summary>
|
/// <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">
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ProjectType>Local</ProjectType>
|
<ProjectType>Local</ProjectType>
|
||||||
|
@ -759,6 +759,7 @@
|
||||||
<Compile Include="Input\JoystickHat.cs" />
|
<Compile Include="Input\JoystickHat.cs" />
|
||||||
<Compile Include="Input\HatPosition.cs" />
|
<Compile Include="Input\HatPosition.cs" />
|
||||||
<Compile Include="Input\JoystickHatState.cs" />
|
<Compile Include="Input\JoystickHatState.cs" />
|
||||||
|
<Compile Include="MouseCursor.cs" />
|
||||||
<Compile Include="Input\KeyModifiers.cs" />
|
<Compile Include="Input\KeyModifiers.cs" />
|
||||||
<Compile Include="Platform\MacOS\CocoaContext.cs" />
|
<Compile Include="Platform\MacOS\CocoaContext.cs" />
|
||||||
<Compile Include="Platform\MacOS\CocoaNativeWindow.cs" />
|
<Compile Include="Platform\MacOS\CocoaNativeWindow.cs" />
|
||||||
|
@ -794,6 +795,7 @@
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Platform\MacOS\Carbon\Cgl.cs" />
|
<Compile Include="Platform\MacOS\Carbon\Cgl.cs" />
|
||||||
|
<Compile Include="WindowIcon.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
@ -823,5 +825,4 @@
|
||||||
</Properties>
|
</Properties>
|
||||||
</MonoDevelop>
|
</MonoDevelop>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
<ItemGroup />
|
|
||||||
</Project>
|
</Project>
|
|
@ -83,6 +83,8 @@ namespace OpenTK.Platform.MacOS
|
||||||
float mouse_rel_x;
|
float mouse_rel_x;
|
||||||
float mouse_rel_y;
|
float mouse_rel_y;
|
||||||
|
|
||||||
|
MouseCursor cursor = MouseCursor.Default;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region AGL Device Hack
|
#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
|
public bool CursorVisible
|
||||||
{
|
{
|
||||||
get { return CG.CursorIsVisible(); }
|
get { return CG.CursorIsVisible(); }
|
||||||
|
|
|
@ -112,6 +112,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
//static readonly IntPtr selIsInFullScreenMode = Selector.Get("isInFullScreenMode");
|
//static readonly IntPtr selIsInFullScreenMode = Selector.Get("isInFullScreenMode");
|
||||||
//static readonly IntPtr selExitFullScreenModeWithOptions = Selector.Get("exitFullScreenModeWithOptions:");
|
//static readonly IntPtr selExitFullScreenModeWithOptions = Selector.Get("exitFullScreenModeWithOptions:");
|
||||||
//static readonly IntPtr selEnterFullScreenModeWithOptions = Selector.Get("enterFullScreenMode:withOptions:");
|
//static readonly IntPtr selEnterFullScreenModeWithOptions = Selector.Get("enterFullScreenMode:withOptions:");
|
||||||
|
static readonly IntPtr selArrowCursor = Selector.Get("arrowCursor");
|
||||||
|
|
||||||
static readonly IntPtr NSDefaultRunLoopMode;
|
static readonly IntPtr NSDefaultRunLoopMode;
|
||||||
static readonly IntPtr NSCursor;
|
static readonly IntPtr NSCursor;
|
||||||
|
@ -142,8 +143,10 @@ namespace OpenTK.Platform.MacOS
|
||||||
private int normalLevel;
|
private int normalLevel;
|
||||||
private bool shouldClose;
|
private bool shouldClose;
|
||||||
private int suppressResize;
|
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;
|
private const bool exclusiveFullscreen = false;
|
||||||
|
|
||||||
public CocoaNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
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);
|
var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner);
|
||||||
if (trackingAreaOwner == windowInfo.ViewHandle)
|
if (trackingAreaOwner == windowInfo.ViewHandle)
|
||||||
{
|
{
|
||||||
if (!cursorVisible)
|
if (selectedCursor != MouseCursor.Default)
|
||||||
{
|
{
|
||||||
SetCursorVisible(false);
|
SetCursor(selectedCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursorInsideWindow = true;
|
||||||
MouseEnter(this, EventArgs.Empty);
|
MouseEnter(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -428,11 +432,12 @@ namespace OpenTK.Platform.MacOS
|
||||||
var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner);
|
var trackingAreaOwner = Cocoa.SendIntPtr(eventTrackingArea, selOwner);
|
||||||
if (trackingAreaOwner == windowInfo.ViewHandle)
|
if (trackingAreaOwner == windowInfo.ViewHandle)
|
||||||
{
|
{
|
||||||
if (!cursorVisible)
|
if (selectedCursor != MouseCursor.Default)
|
||||||
{
|
{
|
||||||
SetCursorVisible(true);
|
SetCursor(MouseCursor.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cursorInsideWindow = false;
|
||||||
MouseLeave(this, EventArgs.Empty);
|
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
|
public bool CursorVisible
|
||||||
{
|
{
|
||||||
get { return cursorVisible; }
|
get { return cursorVisible; }
|
||||||
|
@ -966,11 +992,26 @@ namespace OpenTK.Platform.MacOS
|
||||||
|
|
||||||
private void SetCursorVisible(bool visible)
|
private void SetCursorVisible(bool visible)
|
||||||
{
|
{
|
||||||
// Problem: Unlike the PC version, you can move the mouse out of the window.
|
Carbon.CG.AssociateMouseAndMouseCursorPosition(visible);
|
||||||
// Perhaps use CG.WarpMouseCursorPosition to clamp mouse?
|
|
||||||
Cocoa.SendVoid(NSCursor, visible ? selUnhide : selHide);
|
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)
|
private void SetMenuVisible(bool visible)
|
||||||
{
|
{
|
||||||
var options = (NSApplicationPresentationOptions)Cocoa.SendInt(NSApplication.Handle, selPresentationOptions);
|
var options = (NSApplicationPresentationOptions)Cocoa.SendInt(NSApplication.Handle, selPresentationOptions);
|
||||||
|
|
|
@ -33,6 +33,8 @@ using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace OpenTK.Platform.SDL2
|
namespace OpenTK.Platform.SDL2
|
||||||
{
|
{
|
||||||
|
using Surface = IntPtr;
|
||||||
|
using Cursor = IntPtr;
|
||||||
|
|
||||||
partial class SDL
|
partial class SDL
|
||||||
{
|
{
|
||||||
|
@ -77,6 +79,26 @@ namespace OpenTK.Platform.SDL2
|
||||||
// strlen++;
|
// 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]
|
[SuppressUnmanagedCodeSecurity]
|
||||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_AddEventWatch", ExactSpelling = true)]
|
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_AddEventWatch", ExactSpelling = true)]
|
||||||
public static extern void AddEventWatch(EventFilter filter, IntPtr userdata);
|
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)]
|
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetModState", ExactSpelling = true)]
|
||||||
public static extern Keymod GetModState();
|
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]
|
[SuppressUnmanagedCodeSecurity]
|
||||||
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetNumDisplayModes", ExactSpelling = true)]
|
[DllImport(lib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_GetNumDisplayModes", ExactSpelling = true)]
|
||||||
public static extern int GetNumDisplayModes(int displayIndex);
|
public static extern int GetNumDisplayModes(int displayIndex);
|
||||||
|
|
|
@ -58,6 +58,8 @@ namespace OpenTK.Platform.SDL2
|
||||||
WindowState previous_window_state = WindowState.Normal;
|
WindowState previous_window_state = WindowState.Normal;
|
||||||
WindowBorder window_border = WindowBorder.Resizable;
|
WindowBorder window_border = WindowBorder.Resizable;
|
||||||
Icon icon;
|
Icon icon;
|
||||||
|
MouseCursor cursor = MouseCursor.Default;
|
||||||
|
IntPtr sdl_cursor = IntPtr.Zero;
|
||||||
string window_title;
|
string window_title;
|
||||||
|
|
||||||
// Used in KeyPress event to decode SDL UTF8 text strings
|
// 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> MouseEnter = delegate { };
|
||||||
public event EventHandler<EventArgs> MouseLeave = 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()
|
public void Close()
|
||||||
{
|
{
|
||||||
lock (sync)
|
lock (sync)
|
||||||
|
|
|
@ -856,6 +856,98 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#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)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern BOOL SetForegroundWindow(HWND hWnd);
|
public static extern BOOL SetForegroundWindow(HWND hWnd);
|
||||||
|
|
||||||
|
@ -1043,6 +1135,53 @@ namespace OpenTK.Platform.Windows
|
||||||
uint cbSize, MouseMovePoint* pointsIn,
|
uint cbSize, MouseMovePoint* pointsIn,
|
||||||
MouseMovePoint* pointsBufferOut, int nBufPoints, uint resolution);
|
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 Async input
|
||||||
|
|
||||||
#region GetCursorPos
|
#region GetCursorPos
|
||||||
|
@ -3007,6 +3146,57 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#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
|
#endregion
|
||||||
|
|
||||||
#region --- Enums ---
|
#region --- Enums ---
|
||||||
|
|
|
@ -101,6 +101,8 @@ namespace OpenTK.Platform.Windows
|
||||||
KeyboardKeyEventArgs key_up = new KeyboardKeyEventArgs();
|
KeyboardKeyEventArgs key_up = new KeyboardKeyEventArgs();
|
||||||
KeyPressEventArgs key_press = new KeyPressEventArgs((char)0);
|
KeyPressEventArgs key_press = new KeyPressEventArgs((char)0);
|
||||||
|
|
||||||
|
MouseCursor cursor = MouseCursor.Default;
|
||||||
|
IntPtr curson_handle = IntPtr.Zero;
|
||||||
int cursor_visible_count = 0;
|
int cursor_visible_count = 0;
|
||||||
|
|
||||||
static readonly object SyncRoot = new object();
|
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)
|
void HandleChar(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
char c;
|
char c;
|
||||||
|
@ -653,6 +666,8 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
|
IntPtr? result = null;
|
||||||
|
|
||||||
switch (message)
|
switch (message)
|
||||||
{
|
{
|
||||||
#region Size / Move / Style events
|
#region Size / Move / Style events
|
||||||
|
@ -686,6 +701,10 @@ namespace OpenTK.Platform.Windows
|
||||||
HandleSize(handle, message, wParam, lParam);
|
HandleSize(handle, message, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WindowMessage.SETCURSOR:
|
||||||
|
result = HandleSetCursor(handle, message, wParam, lParam);
|
||||||
|
break;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Input events
|
#region Input events
|
||||||
|
@ -772,8 +791,15 @@ namespace OpenTK.Platform.Windows
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.HasValue)
|
||||||
|
{
|
||||||
|
return result.Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return Functions.DefWindowProc(handle, message, wParam, lParam);
|
return Functions.DefWindowProc(handle, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void EnableMouseTracking()
|
private void EnableMouseTracking()
|
||||||
{
|
{
|
||||||
|
@ -1165,6 +1191,66 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Cursor
|
||||||
|
|
||||||
|
public MouseCursor Cursor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != cursor)
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
bool destoryOld = cursor != MouseCursor.Default;
|
||||||
|
|
||||||
|
cursor = value;
|
||||||
|
curson_handle = icon;
|
||||||
|
var oldCursor = Functions.SetCursor(icon);
|
||||||
|
|
||||||
|
if (destoryOld)
|
||||||
|
{
|
||||||
|
Functions.DestroyIcon(oldCursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region CursorVisible
|
#region CursorVisible
|
||||||
|
|
||||||
public bool CursorVisible
|
public bool CursorVisible
|
||||||
|
|
|
@ -38,6 +38,11 @@ namespace OpenTK.Platform.X11
|
||||||
using Display = System.IntPtr;
|
using Display = System.IntPtr;
|
||||||
using XPointer = 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
|
// Randr and Xrandr
|
||||||
using Bool = System.Boolean;
|
using Bool = System.Boolean;
|
||||||
using XRRScreenConfiguration = System.IntPtr; // opaque datatype
|
using XRRScreenConfiguration = System.IntPtr; // opaque datatype
|
||||||
|
@ -579,6 +584,47 @@ XF86VidModeGetGammaRampSize(
|
||||||
|
|
||||||
#region X11 Structures
|
#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
|
#region internal class XVisualInfo
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
@ -1388,6 +1434,7 @@ XF86VidModeGetGammaRampSize(
|
||||||
internal static partial class Functions
|
internal static partial class Functions
|
||||||
{
|
{
|
||||||
internal const string X11Library = "libX11";
|
internal const string X11Library = "libX11";
|
||||||
|
internal const string XcursorLibrary = "libXcursor.so.1";
|
||||||
|
|
||||||
#region XCreateWindow
|
#region XCreateWindow
|
||||||
|
|
||||||
|
@ -1434,6 +1481,19 @@ XF86VidModeGetGammaRampSize(
|
||||||
|
|
||||||
#endregion
|
#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
|
#region XQueryKeymap
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -115,6 +115,9 @@ namespace OpenTK.Platform.X11
|
||||||
bool isExiting;
|
bool isExiting;
|
||||||
|
|
||||||
bool _decorations_hidden = false;
|
bool _decorations_hidden = false;
|
||||||
|
|
||||||
|
MouseCursor cursor = MouseCursor.Default;
|
||||||
|
IntPtr cursorHandle;
|
||||||
bool cursor_visible = true;
|
bool cursor_visible = true;
|
||||||
int mouse_rel_x, mouse_rel_y;
|
int mouse_rel_x, mouse_rel_y;
|
||||||
|
|
||||||
|
@ -1460,6 +1463,48 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#endregion
|
#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
|
public bool CursorVisible
|
||||||
{
|
{
|
||||||
get { return cursor_visible; }
|
get { return cursor_visible; }
|
||||||
|
@ -1469,7 +1514,7 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
using (new XLock(window.Display))
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
Functions.XUndefineCursor(window.Display, window.Handle);
|
Functions.XDefineCursor(window.Display, window.Handle, cursorHandle);
|
||||||
cursor_visible = true;
|
cursor_visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1486,6 +1531,8 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region --- INativeGLWindow Members ---
|
#region --- INativeGLWindow Members ---
|
||||||
|
|
||||||
#region public IInputDriver InputDriver
|
#region public IInputDriver InputDriver
|
||||||
|
@ -1704,6 +1751,10 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
using (new XLock(window.Display))
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
|
if(cursorHandle != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Functions.XFreeCursor(window.Display, cursorHandle);
|
||||||
|
}
|
||||||
Functions.XFreeCursor(window.Display, EmptyCursor);
|
Functions.XFreeCursor(window.Display, EmptyCursor);
|
||||||
Functions.XDestroyWindow(window.Display, window.Handle);
|
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