mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-07-07 16:10:44 +00:00
Merge pull request #114 from thefiddler/nativewindow
INativeWindow cleanup and consolidation
This commit is contained in:
commit
cd7342b688
|
@ -572,6 +572,7 @@
|
||||||
<Link>Dependencies\x64\libSDL2.dylib</Link>
|
<Link>Dependencies\x64\libSDL2.dylib</Link>
|
||||||
</None>
|
</None>
|
||||||
<Compile Include="OpenTK\Test\ExternalContext.cs" />
|
<Compile Include="OpenTK\Test\ExternalContext.cs" />
|
||||||
|
<Compile Include="OpenTK\Test\PointToClient.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||||
|
|
|
@ -26,6 +26,28 @@ namespace Examples.Tests
|
||||||
bool mouse_in_window = false;
|
bool mouse_in_window = false;
|
||||||
bool viewport_changed = true;
|
bool viewport_changed = true;
|
||||||
|
|
||||||
|
MouseCursor Pencil;
|
||||||
|
|
||||||
|
// legacy GameWindow.Mouse.* events
|
||||||
|
Vector4 mousedevice_pos;
|
||||||
|
int mousedevice_buttons;
|
||||||
|
MouseState mousedevice_state;
|
||||||
|
|
||||||
|
// new GameWindow.Mouse* events
|
||||||
|
Vector4 mouse_pos;
|
||||||
|
int mouse_buttons;
|
||||||
|
MouseState mouse_state;
|
||||||
|
|
||||||
|
// legacy GameWindow.Keyboard.Key* events
|
||||||
|
Dictionary<Key, int> legacy_keyboard_keys = new Dictionary<Key, int>();
|
||||||
|
KeyboardState legacy_keyboard_state;
|
||||||
|
KeyModifiers legacy_keyboard_modifiers;
|
||||||
|
|
||||||
|
//new GameWindow.Key* events
|
||||||
|
Dictionary<Key, int> keyboard_keys = new Dictionary<Key, int>();
|
||||||
|
KeyboardState keyboard_state;
|
||||||
|
KeyModifiers keyboard_modifiers;
|
||||||
|
|
||||||
// time drift
|
// time drift
|
||||||
Stopwatch watch = new Stopwatch();
|
Stopwatch watch = new Stopwatch();
|
||||||
double update_time, render_time;
|
double update_time, render_time;
|
||||||
|
@ -42,8 +64,6 @@ namespace Examples.Tests
|
||||||
double variable_refresh_timestep_pos = -1;
|
double variable_refresh_timestep_pos = -1;
|
||||||
double fixed_update_timestep_pos = -1;
|
double fixed_update_timestep_pos = -1;
|
||||||
|
|
||||||
KeyModifiers modifiers;
|
|
||||||
|
|
||||||
public GameWindowStates()
|
public GameWindowStates()
|
||||||
: base(800, 600, GraphicsMode.Default)
|
: base(800, 600, GraphicsMode.Default)
|
||||||
{
|
{
|
||||||
|
@ -52,16 +72,26 @@ namespace Examples.Tests
|
||||||
KeyDown += KeyDownHandler;
|
KeyDown += KeyDownHandler;
|
||||||
KeyUp += KeyUpHandler;
|
KeyUp += KeyUpHandler;
|
||||||
KeyPress += KeyPressHandler;
|
KeyPress += KeyPressHandler;
|
||||||
|
Keyboard.KeyDown += KeyboardDeviceDownHandler;
|
||||||
|
Keyboard.KeyUp += KeyboardDeviceUpHandler;
|
||||||
|
|
||||||
MouseEnter += delegate { mouse_in_window = true; };
|
MouseEnter += delegate { mouse_in_window = true; };
|
||||||
MouseLeave += delegate { mouse_in_window = false; };
|
MouseLeave += delegate { mouse_in_window = false; };
|
||||||
|
|
||||||
Mouse.Move += MouseMoveHandler;
|
Mouse.Move += MouseDeviceMoveHandler;
|
||||||
Mouse.ButtonDown += MouseButtonHandler;
|
Mouse.WheelChanged += MouseDeviceWheelHandler;
|
||||||
Mouse.ButtonUp += MouseButtonHandler;
|
Mouse.ButtonDown += MouseDeviceButtonHandler;
|
||||||
|
Mouse.ButtonUp += MouseDeviceButtonHandler;
|
||||||
|
|
||||||
|
MouseMove += MouseMoveHandler;
|
||||||
|
MouseWheel += MouseWheelHandler;
|
||||||
|
MouseDown += MouseButtonHandler;
|
||||||
|
MouseUp += MouseButtonHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void KeyPressHandler(object sender, KeyPressEventArgs e)
|
#region Keyboard Events
|
||||||
|
|
||||||
|
void KeyPressHandler(object sender, KeyPressEventArgs e)
|
||||||
{
|
{
|
||||||
if (TypedText.Length > 32)
|
if (TypedText.Length > 32)
|
||||||
TypedText.Remove(0, 1);
|
TypedText.Remove(0, 1);
|
||||||
|
@ -108,26 +138,117 @@ namespace Examples.Tests
|
||||||
case Key.BracketRight: TargetUpdateFrequency++; break;
|
case Key.BracketRight: TargetUpdateFrequency++; break;
|
||||||
case Key.Comma: TargetRenderFrequency--; break;
|
case Key.Comma: TargetRenderFrequency--; break;
|
||||||
case Key.Period: TargetRenderFrequency++; break;
|
case Key.Period: TargetRenderFrequency++; break;
|
||||||
|
|
||||||
|
case Key.Space:
|
||||||
|
CursorVisible = !CursorVisible;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
modifiers = e.Modifiers;
|
|
||||||
|
if (!keyboard_keys.ContainsKey(e.Key))
|
||||||
|
{
|
||||||
|
keyboard_keys.Add(e.Key, 0);
|
||||||
|
}
|
||||||
|
keyboard_keys[e.Key] = e.IsRepeat ? 1 : 0;
|
||||||
|
keyboard_modifiers = e.Modifiers;
|
||||||
|
keyboard_state = e.Keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyUpHandler(object sender, KeyboardKeyEventArgs e)
|
void KeyUpHandler(object sender, KeyboardKeyEventArgs e)
|
||||||
{
|
{
|
||||||
modifiers = e.Modifiers;
|
keyboard_keys.Remove(e.Key);
|
||||||
|
keyboard_modifiers = e.Modifiers;
|
||||||
|
keyboard_state = e.Keyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KeyboardDeviceDownHandler(object sender, KeyboardKeyEventArgs e)
|
||||||
|
{
|
||||||
|
if (!legacy_keyboard_keys.ContainsKey(e.Key))
|
||||||
|
{
|
||||||
|
legacy_keyboard_keys.Add(e.Key, 0);
|
||||||
|
}
|
||||||
|
legacy_keyboard_keys[e.Key] = e.IsRepeat ? 1 : 0;
|
||||||
|
legacy_keyboard_modifiers = e.Modifiers;
|
||||||
|
legacy_keyboard_state = e.Keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardDeviceUpHandler(object sender, KeyboardKeyEventArgs e)
|
||||||
|
{
|
||||||
|
legacy_keyboard_keys.Remove(e.Key);
|
||||||
|
legacy_keyboard_modifiers = e.Modifiers;
|
||||||
|
legacy_keyboard_state = e.Keyboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region MouseDevice events
|
||||||
|
|
||||||
|
void MouseDeviceMoveHandler(object sender, MouseMoveEventArgs e)
|
||||||
|
{
|
||||||
|
mousedevice_pos.X = e.X;
|
||||||
|
mousedevice_pos.Y = e.Y;
|
||||||
|
mousedevice_pos.Z = e.Mouse.Scroll.X;
|
||||||
|
mousedevice_pos.W = e.Mouse.Scroll.Y;
|
||||||
|
mousedevice_state = e.Mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseDeviceButtonHandler(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.IsPressed)
|
||||||
|
{
|
||||||
|
mousedevice_buttons |= 1 << (int)e.Button;
|
||||||
|
Cursor = Pencil;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mousedevice_buttons &= ~(1 << (int)e.Button);
|
||||||
|
Cursor = MouseCursor.Default;
|
||||||
|
}
|
||||||
|
mousedevice_state = e.Mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseDeviceWheelHandler(object sender, MouseWheelEventArgs e)
|
||||||
|
{
|
||||||
|
mousedevice_pos.Z = e.Mouse.Scroll.X;
|
||||||
|
mousedevice_pos.W = e.Mouse.Scroll.Y;
|
||||||
|
mousedevice_state = e.Mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Mouse events
|
||||||
|
|
||||||
void MouseMoveHandler(object sender, MouseMoveEventArgs e)
|
void MouseMoveHandler(object sender, MouseMoveEventArgs e)
|
||||||
{
|
{
|
||||||
|
mouse_pos.X = e.X;
|
||||||
|
mouse_pos.Y = e.Y;
|
||||||
|
mouse_pos.Z = e.Mouse.Scroll.X;
|
||||||
|
mouse_pos.W = e.Mouse.Scroll.Y;
|
||||||
|
mouse_state = e.Mouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseButtonHandler(object sender, MouseButtonEventArgs e)
|
void MouseButtonHandler(object sender, MouseButtonEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.Button == MouseButton.Left && e.IsPressed)
|
if (e.IsPressed)
|
||||||
{
|
{
|
||||||
CursorVisible = false;
|
mouse_buttons |= 1 << (int)e.Button;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mouse_buttons &= ~(1 << (int)e.Button);
|
||||||
}
|
}
|
||||||
|
mouse_state = e.Mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MouseWheelHandler(object sender, MouseWheelEventArgs e)
|
||||||
|
{
|
||||||
|
mouse_pos.Z = e.Mouse.Scroll.X;
|
||||||
|
mouse_pos.W = e.Mouse.Scroll.Y;
|
||||||
|
mouse_state = e.Mouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Private Members
|
||||||
|
|
||||||
static int Clamp(int val, int min, int max)
|
static int Clamp(int val, int min, int max)
|
||||||
{
|
{
|
||||||
|
@ -145,18 +266,8 @@ namespace Examples.Tests
|
||||||
return offset + gfx.MeasureString(str, TextFont).Width;
|
return offset + gfx.MeasureString(str, TextFont).Width;
|
||||||
}
|
}
|
||||||
|
|
||||||
int DrawKeyboards(Graphics gfx, int line)
|
static void KeyboardStateToString(KeyboardState state, StringBuilder sb)
|
||||||
{
|
{
|
||||||
line++;
|
|
||||||
DrawString(gfx, String.Format("Keyboard ({0}):", modifiers), line++);
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
var state = OpenTK.Input.Keyboard.GetState(i);
|
|
||||||
if (state.IsConnected)
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.Append(i);
|
|
||||||
sb.Append(": ");
|
|
||||||
for (int key_index = 0; key_index < (int)Key.LastKey; key_index++)
|
for (int key_index = 0; key_index < (int)Key.LastKey; key_index++)
|
||||||
{
|
{
|
||||||
Key k = (Key)key_index;
|
Key k = (Key)key_index;
|
||||||
|
@ -166,6 +277,21 @@ namespace Examples.Tests
|
||||||
sb.Append(" ");
|
sb.Append(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DrawKeyboards(Graphics gfx, int line)
|
||||||
|
{
|
||||||
|
line++;
|
||||||
|
DrawString(gfx, "Keyboard:", line++);
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
var state = OpenTK.Input.Keyboard.GetState(i);
|
||||||
|
if (state.IsConnected)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append(i);
|
||||||
|
sb.Append(": ");
|
||||||
|
KeyboardStateToString(state, sb);
|
||||||
DrawString(gfx, sb.ToString(), line++);
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,6 +327,112 @@ namespace Examples.Tests
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DrawKeyboardDevice(Graphics gfx, int line)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("KeyboardDevice: ");
|
||||||
|
for (Key key = 0; key < Key.LastKey; key++)
|
||||||
|
{
|
||||||
|
if (Keyboard[key])
|
||||||
|
{
|
||||||
|
sb.Append(key);
|
||||||
|
sb.Append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
|
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
sb.Append("KeyboardDevice events: [");
|
||||||
|
sb.Append(legacy_keyboard_modifiers);
|
||||||
|
sb.Append("] ");
|
||||||
|
foreach (var pair in legacy_keyboard_keys)
|
||||||
|
{
|
||||||
|
sb.Append(pair.Key);
|
||||||
|
sb.Append(":");
|
||||||
|
sb.Append(pair.Value);
|
||||||
|
sb.Append(" ");
|
||||||
|
}
|
||||||
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
|
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
sb.Append("KeyboardDevice state: ");
|
||||||
|
KeyboardStateToString(legacy_keyboard_state, sb);
|
||||||
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
|
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
sb.Append("Keyboard events: [");
|
||||||
|
sb.Append(keyboard_modifiers);
|
||||||
|
sb.Append("] ");
|
||||||
|
foreach (var pair in keyboard_keys)
|
||||||
|
{
|
||||||
|
sb.Append(pair.Key);
|
||||||
|
sb.Append(":");
|
||||||
|
sb.Append(pair.Value);
|
||||||
|
sb.Append(" ");
|
||||||
|
}
|
||||||
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
|
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
sb.Append("Keyboard state: ");
|
||||||
|
KeyboardStateToString(keyboard_state, sb);
|
||||||
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
|
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DrawMouseDevice(Graphics gfx, int line)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.Append("MouseDevice: ");
|
||||||
|
sb.AppendFormat("[{0}, {1}, {2:0.00}] ",
|
||||||
|
Mouse.X, Mouse.Y, Mouse.WheelPrecise);
|
||||||
|
for (var i = MouseButton.Left; i < MouseButton.LastButton; i++)
|
||||||
|
{
|
||||||
|
if (Mouse[i])
|
||||||
|
{
|
||||||
|
sb.Append(i);
|
||||||
|
sb.Append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.AppendLine();
|
||||||
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
|
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
sb.Append("MouseDevice events: ");
|
||||||
|
sb.AppendFormat("[{0}, {1}, {2:0.00}, {3:0.00}] ",
|
||||||
|
mousedevice_pos.X, mousedevice_pos.Y,
|
||||||
|
mousedevice_pos.Z, mousedevice_pos.W);
|
||||||
|
for (var i = MouseButton.Left; i < MouseButton.LastButton; i++)
|
||||||
|
{
|
||||||
|
if ((mousedevice_buttons & (1 << (int)i)) != 0)
|
||||||
|
{
|
||||||
|
sb.Append(i);
|
||||||
|
sb.Append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.Append(" ");
|
||||||
|
sb.AppendLine(mousedevice_state.ToString());
|
||||||
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
|
|
||||||
|
sb.Remove(0, sb.Length);
|
||||||
|
sb.Append("Mouse events: ");
|
||||||
|
sb.AppendFormat("[{0}, {1}, {2:0.00}, {3:0.00}] ",
|
||||||
|
mouse_pos.X, mouse_pos.Y,
|
||||||
|
mouse_pos.Z, mouse_pos.W);
|
||||||
|
for (var i = MouseButton.Left; i < MouseButton.LastButton; i++)
|
||||||
|
{
|
||||||
|
if ((mouse_buttons & (1 << (int)i)) != 0)
|
||||||
|
{
|
||||||
|
sb.Append(i);
|
||||||
|
sb.Append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.Append(" ");
|
||||||
|
sb.AppendLine(mouse_state.ToString());
|
||||||
|
DrawString(gfx, sb.ToString(), line++);
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
static int DrawLegacyJoysticks(Graphics gfx, IList<JoystickDevice> joysticks, int line)
|
static int DrawLegacyJoysticks(Graphics gfx, IList<JoystickDevice> joysticks, int line)
|
||||||
{
|
{
|
||||||
line++;
|
line++;
|
||||||
|
@ -236,6 +468,8 @@ namespace Examples.Tests
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
protected override void OnUpdateFrame(FrameEventArgs e)
|
protected override void OnUpdateFrame(FrameEventArgs e)
|
||||||
{
|
{
|
||||||
double clock_time = watch.Elapsed.TotalSeconds;
|
double clock_time = watch.Elapsed.TotalSeconds;
|
||||||
|
@ -267,7 +501,9 @@ namespace Examples.Tests
|
||||||
mouse_in_window ? "inside" : "outside",
|
mouse_in_window ? "inside" : "outside",
|
||||||
CursorVisible ? "visible" : "hidden",
|
CursorVisible ? "visible" : "hidden",
|
||||||
Focused ? "Focused" : "Not focused"), line++);
|
Focused ? "Focused" : "Not focused"), line++);
|
||||||
DrawString(gfx, String.Format("Mouse coordinates: {0}", new Vector3(Mouse.X, Mouse.Y, Mouse.WheelPrecise)), line++);
|
|
||||||
|
line = DrawKeyboardDevice(gfx, line);
|
||||||
|
line = DrawMouseDevice(gfx, line);
|
||||||
|
|
||||||
// Timing information
|
// Timing information
|
||||||
line++;
|
line++;
|
||||||
|
@ -350,6 +586,17 @@ namespace Examples.Tests
|
||||||
{
|
{
|
||||||
watch.Start();
|
watch.Start();
|
||||||
|
|
||||||
|
using (var bitmap = new Bitmap("Data/Textures/cursor.png"))
|
||||||
|
{
|
||||||
|
var data = bitmap.LockBits(
|
||||||
|
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
|
||||||
|
System.Drawing.Imaging.ImageLockMode.ReadOnly,
|
||||||
|
System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
|
||||||
|
|
||||||
|
Pencil = new OpenTK.MouseCursor(
|
||||||
|
2, 21, data.Width, data.Height, data.Scan0);
|
||||||
|
}
|
||||||
|
|
||||||
GL.ClearColor(Color.MidnightBlue);
|
GL.ClearColor(Color.MidnightBlue);
|
||||||
|
|
||||||
GL.Enable(EnableCap.Texture2D);
|
GL.Enable(EnableCap.Texture2D);
|
||||||
|
|
37
Source/Examples/OpenTK/Test/PointToClient.cs
Normal file
37
Source/Examples/OpenTK/Test/PointToClient.cs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using OpenTK;
|
||||||
|
|
||||||
|
namespace Examples.Tests
|
||||||
|
{
|
||||||
|
[Example("PointToClient Test", ExampleCategory.OpenTK, "NativeWindow")]
|
||||||
|
public class PointToClientTest
|
||||||
|
{
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
using (var window = new NativeWindow())
|
||||||
|
{
|
||||||
|
Trace.WriteLine(String.Format("Window bounds: {0}", window.Bounds));
|
||||||
|
Trace.WriteLine(String.Format("Window client: {0}", window.ClientRectangle));
|
||||||
|
|
||||||
|
Point pclient = new Point(100, 100);
|
||||||
|
Point pscreen = window.PointToScreen(pclient);
|
||||||
|
Point ptest = window.PointToClient(pscreen);
|
||||||
|
Trace.WriteLine(String.Format("Client: {0} -> Screen: {1} -> Client: {2}",
|
||||||
|
pclient, pscreen, ptest));
|
||||||
|
Trace.WriteLine(String.Format("Test {0}",
|
||||||
|
ptest == pclient ? "succeeded" : "failed"));
|
||||||
|
|
||||||
|
pscreen = new Point(100, 100);
|
||||||
|
pclient = window.PointToClient(pscreen);
|
||||||
|
ptest = window.PointToScreen(pclient);
|
||||||
|
Trace.WriteLine(String.Format("Screen: {0} -> Client: {1} -> Screen: {2}",
|
||||||
|
pscreen, pclient, ptest));
|
||||||
|
Trace.WriteLine(String.Format("Test {0}",
|
||||||
|
ptest == pscreen ? "succeeded" : "failed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -51,9 +51,9 @@ namespace OpenTK.Graphics
|
||||||
protected string[] EntryPointNamesInstance;
|
protected string[] EntryPointNamesInstance;
|
||||||
|
|
||||||
|
|
||||||
internal protected IntPtr[] _EntryPointsInstance;
|
internal IntPtr[] _EntryPointsInstance;
|
||||||
internal protected byte[] _EntryPointNamesInstance;
|
internal byte[] _EntryPointNamesInstance;
|
||||||
internal protected int[] _EntryPointNameOffsetsInstance;
|
internal int[] _EntryPointNameOffsetsInstance;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves an unmanaged function pointer to the specified function.
|
/// Retrieves an unmanaged function pointer to the specified function.
|
||||||
|
|
|
@ -260,10 +260,26 @@ namespace OpenTK
|
||||||
/// </summary>
|
/// </summary>
|
||||||
event EventHandler<EventArgs> MouseEnter;
|
event EventHandler<EventArgs> MouseEnter;
|
||||||
|
|
||||||
//event EventHandler<MouseEventArgs> MouseMove;
|
/// <summary>
|
||||||
//event EventHandler<MouseEventArgs> MouseWheel;
|
/// Occurs whenever a <see cref="MouseButton"/> is clicked.
|
||||||
//event EventHandler<MouseEventArgs> MouseDown;
|
/// </summary>
|
||||||
//event EventHandler<MouseEventArgs> MouseUp;
|
event EventHandler<Input.MouseButtonEventArgs> MouseDown;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs whenever a <see cref="MouseButton"/> is released.
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<Input.MouseButtonEventArgs> MouseUp;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs whenever the mouse cursor is moved;
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<Input.MouseMoveEventArgs> MouseMove;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs whenever a mouse wheel is moved;
|
||||||
|
/// </summary>
|
||||||
|
event EventHandler<Input.MouseWheelEventArgs> MouseWheel;
|
||||||
|
|
||||||
//event EventHandler<MouseEventArgs> MouseClick;
|
//event EventHandler<MouseEventArgs> MouseClick;
|
||||||
//event EventHandler<MouseEventArgs> MouseDoubleClick;
|
//event EventHandler<MouseEventArgs> MouseDoubleClick;
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,11 @@ namespace OpenTK.Input
|
||||||
public sealed class KeyboardDevice : IInputDevice
|
public sealed class KeyboardDevice : IInputDevice
|
||||||
{
|
{
|
||||||
//private IKeyboard keyboard;
|
//private IKeyboard keyboard;
|
||||||
private bool[] keys = new bool[(int)Key.LastKey];
|
|
||||||
private bool[] scancodes = new bool[256];
|
|
||||||
private string description;
|
private string description;
|
||||||
private int numKeys, numFKeys, numLeds;
|
private int numKeys, numFKeys, numLeds;
|
||||||
private IntPtr devID;
|
private IntPtr devID;
|
||||||
private bool repeat;
|
private bool repeat;
|
||||||
private KeyboardKeyEventArgs args = new KeyboardKeyEventArgs();
|
private KeyboardState state;
|
||||||
|
|
||||||
#region --- Constructors ---
|
#region --- Constructors ---
|
||||||
|
|
||||||
|
@ -44,7 +42,7 @@ namespace OpenTK.Input
|
||||||
/// <returns>True if the Key is pressed, false otherwise.</returns>
|
/// <returns>True if the Key is pressed, false otherwise.</returns>
|
||||||
public bool this[Key key]
|
public bool this[Key key]
|
||||||
{
|
{
|
||||||
get { return keys[(int)key]; }
|
get { return state[key]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -52,9 +50,10 @@ namespace OpenTK.Input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="scancode">The scancode to check.</param>
|
/// <param name="scancode">The scancode to check.</param>
|
||||||
/// <returns>True if the scancode is pressed, false otherwise.</returns>
|
/// <returns>True if the scancode is pressed, false otherwise.</returns>
|
||||||
|
[CLSCompliant(false)]
|
||||||
public bool this[uint scancode]
|
public bool this[uint scancode]
|
||||||
{
|
{
|
||||||
get { return scancodes[scancode]; }
|
get { return scancode < (uint)Key.LastKey && state[(Key)scancode]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -124,7 +123,7 @@ namespace OpenTK.Input
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a key is pressed.
|
/// Occurs when a key is pressed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<KeyboardKeyEventArgs> KeyDown;
|
public event EventHandler<KeyboardKeyEventArgs> KeyDown = delegate { };
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -133,7 +132,7 @@ namespace OpenTK.Input
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a key is released.
|
/// Occurs when a key is released.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<KeyboardKeyEventArgs> KeyUp;
|
public event EventHandler<KeyboardKeyEventArgs> KeyUp = delegate { };
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -185,21 +184,22 @@ namespace OpenTK.Input
|
||||||
|
|
||||||
#region --- Internal Methods ---
|
#region --- Internal Methods ---
|
||||||
|
|
||||||
#region internal void ClearKeys()
|
internal void HandleKeyDown(object sender, KeyboardKeyEventArgs e)
|
||||||
|
|
||||||
internal void ClearKeys()
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < keys.Length; i++)
|
state = e.Keyboard;
|
||||||
keys[i] = false;
|
KeyDown(this, e);
|
||||||
for (uint i = 0; i < scancodes.Length; i++)
|
|
||||||
scancodes[i] = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
internal void HandleKeyUp(object sender, KeyboardKeyEventArgs e)
|
||||||
|
|
||||||
internal void SetKey(Key key, uint scancode, bool state)
|
|
||||||
{
|
{
|
||||||
if (keys[(int)key] != state || KeyRepeat)
|
state = e.Keyboard;
|
||||||
|
KeyUp(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if false
|
||||||
|
internal void SetKey(Key key, uint scancode, KeyModifiers mods, bool pressed)
|
||||||
|
{
|
||||||
|
if (state[key] != pressed || KeyRepeat)
|
||||||
{
|
{
|
||||||
// limit scancode to 8bits, otherwise the assignment
|
// limit scancode to 8bits, otherwise the assignment
|
||||||
// below will crash randomly
|
// below will crash randomly
|
||||||
|
@ -209,42 +209,22 @@ namespace OpenTK.Input
|
||||||
|
|
||||||
if (state && KeyDown != null)
|
if (state && KeyDown != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
args.Key = key;
|
args.Key = key;
|
||||||
args.ScanCode = scancode;
|
args.ScanCode = scancode;
|
||||||
args.Modifiers = GetModifiers();
|
args.Modifiers = mods;
|
||||||
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();
|
args.Modifiers = mods;
|
||||||
KeyUp(this, args);
|
KeyUp(this, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
internal KeyModifiers GetModifiers()
|
|
||||||
{
|
|
||||||
KeyModifiers mods = 0;
|
|
||||||
|
|
||||||
if (this[Key.AltLeft] || this[Key.AltRight])
|
|
||||||
{
|
|
||||||
mods |= KeyModifiers.Alt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this[Key.ControlLeft] || this[Key.ControlRight])
|
|
||||||
{
|
|
||||||
mods |= KeyModifiers.Control;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this[Key.ShiftLeft] || this[Key.ShiftRight])
|
|
||||||
{
|
|
||||||
mods |= KeyModifiers.Shift;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mods;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,8 @@ namespace OpenTK.Input
|
||||||
#region Fields
|
#region Fields
|
||||||
|
|
||||||
Key key;
|
Key key;
|
||||||
KeyModifiers mods;
|
bool repeat;
|
||||||
uint scancode;
|
KeyboardState state;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -65,7 +65,6 @@ namespace OpenTK.Input
|
||||||
public KeyboardKeyEventArgs(KeyboardKeyEventArgs args)
|
public KeyboardKeyEventArgs(KeyboardKeyEventArgs args)
|
||||||
{
|
{
|
||||||
Key = args.Key;
|
Key = args.Key;
|
||||||
ScanCode = args.ScanCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -87,8 +86,7 @@ namespace OpenTK.Input
|
||||||
[CLSCompliant(false)]
|
[CLSCompliant(false)]
|
||||||
public uint ScanCode
|
public uint ScanCode
|
||||||
{
|
{
|
||||||
get { return scancode; }
|
get { return (uint)Key; }
|
||||||
internal set { scancode = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -97,7 +95,7 @@ namespace OpenTK.Input
|
||||||
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
|
||||||
public bool Alt
|
public bool Alt
|
||||||
{
|
{
|
||||||
get { return (mods & KeyModifiers.Alt) != 0; }
|
get { return state[Key.AltLeft] || state[Key.AltRight]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -106,7 +104,7 @@ namespace OpenTK.Input
|
||||||
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
|
||||||
public bool Control
|
public bool Control
|
||||||
{
|
{
|
||||||
get { return (mods & KeyModifiers.Control) != 0; }
|
get { return state[Key.ControlLeft] || state[Key.ControlRight]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -115,7 +113,7 @@ namespace OpenTK.Input
|
||||||
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if pressed; otherwise, <c>false</c>.</value>
|
||||||
public bool Shift
|
public bool Shift
|
||||||
{
|
{
|
||||||
get { return (mods & KeyModifiers.Shift) != 0; }
|
get { return state[Key.ShiftLeft] || state[Key.ShiftRight]; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -125,8 +123,39 @@ namespace OpenTK.Input
|
||||||
/// <value>The modifiers.</value>
|
/// <value>The modifiers.</value>
|
||||||
public KeyModifiers Modifiers
|
public KeyModifiers Modifiers
|
||||||
{
|
{
|
||||||
get { return mods; }
|
get
|
||||||
internal set { mods = value; }
|
{
|
||||||
|
KeyModifiers mods = 0;
|
||||||
|
mods |= Alt ? KeyModifiers.Alt : 0;
|
||||||
|
mods |= Control ? KeyModifiers.Control : 0;
|
||||||
|
mods |= Shift ? KeyModifiers.Shift : 0;
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current <see cref="OpenTK.Input.KeyboardState"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The keyboard.</value>
|
||||||
|
public KeyboardState Keyboard
|
||||||
|
{
|
||||||
|
get { return state; }
|
||||||
|
internal set { state = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="System.Boolean"/> indicating whether
|
||||||
|
/// this key event is a repeat.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// true, if this event was caused by the user holding down
|
||||||
|
/// a key; false, if this was caused by the user pressing a
|
||||||
|
/// key for the first time.
|
||||||
|
/// </value>
|
||||||
|
public bool IsRepeat
|
||||||
|
{
|
||||||
|
get { return repeat; }
|
||||||
|
internal set { repeat = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -43,9 +43,6 @@ namespace OpenTK.Input
|
||||||
const int NumInts = ((int)Key.LastKey + IntSize - 1) / IntSize;
|
const int NumInts = ((int)Key.LastKey + IntSize - 1) / IntSize;
|
||||||
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
|
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
|
||||||
unsafe fixed int Keys[NumInts];
|
unsafe fixed int Keys[NumInts];
|
||||||
|
|
||||||
const int CodesSize = 256;
|
|
||||||
unsafe fixed int Codes[CodesSize];
|
|
||||||
bool is_connected;
|
bool is_connected;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -61,6 +58,7 @@ namespace OpenTK.Input
|
||||||
public bool this[Key key]
|
public bool this[Key key]
|
||||||
{
|
{
|
||||||
get { return IsKeyDown(key); }
|
get { return IsKeyDown(key); }
|
||||||
|
internal set { SetKeyState(key, value); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -71,7 +69,7 @@ namespace OpenTK.Input
|
||||||
/// <returns>True if code is pressed; false otherwise.</returns>
|
/// <returns>True if code is pressed; false otherwise.</returns>
|
||||||
public bool this[short code]
|
public bool this[short code]
|
||||||
{
|
{
|
||||||
get { return IsKeyDown(code); }
|
get { return IsKeyDown((Key)code); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -89,7 +87,7 @@ namespace OpenTK.Input
|
||||||
/// <param name="code">The scan code to check.</param>
|
/// <param name="code">The scan code to check.</param>
|
||||||
public bool IsKeyDown(short code)
|
public bool IsKeyDown(short code)
|
||||||
{
|
{
|
||||||
return ReadBit(code,true);
|
return code >= 0 && code < (short)Key.LastKey && ReadBit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -107,7 +105,7 @@ namespace OpenTK.Input
|
||||||
/// <param name="code">The scan code to check.</param>
|
/// <param name="code">The scan code to check.</param>
|
||||||
public bool IsKeyUp(short code)
|
public bool IsKeyUp(short code)
|
||||||
{
|
{
|
||||||
return !ReadBit(code,true);
|
return !IsKeyDown(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -212,61 +210,50 @@ namespace OpenTK.Input
|
||||||
|
|
||||||
#region Internal Members
|
#region Internal Members
|
||||||
|
|
||||||
internal void SetKeyState(Key key, byte code, bool down)
|
internal void SetKeyState(Key key, bool down)
|
||||||
{
|
{
|
||||||
if (down)
|
if (down)
|
||||||
{
|
{
|
||||||
EnableBit((int)key);
|
EnableBit((int)key);
|
||||||
EnableBit(code,true);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DisableBit((int)key);
|
DisableBit((int)key);
|
||||||
DisableBit(code, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool ReadBit(int offset, bool ScanCode = false)
|
internal bool ReadBit(int offset)
|
||||||
{
|
{
|
||||||
ValidateOffset(offset, ScanCode);
|
ValidateOffset(offset);
|
||||||
|
|
||||||
int int_offset = offset / 32;
|
int int_offset = offset / 32;
|
||||||
int bit_offset = offset % 32;
|
int bit_offset = offset % 32;
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
if (ScanCode)
|
|
||||||
fixed (int* c = Codes) { return (*(c + int_offset) & (1 << bit_offset)) != 0u; }
|
|
||||||
else
|
|
||||||
fixed (int* k = Keys) { return (*(k + int_offset) & (1 << bit_offset)) != 0u; }
|
fixed (int* k = Keys) { return (*(k + int_offset) & (1 << bit_offset)) != 0u; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void EnableBit(int offset, bool ScanCode = false)
|
internal void EnableBit(int offset)
|
||||||
{
|
{
|
||||||
ValidateOffset(offset, ScanCode);
|
ValidateOffset(offset);
|
||||||
|
|
||||||
int int_offset = offset / 32;
|
int int_offset = offset / 32;
|
||||||
int bit_offset = offset % 32;
|
int bit_offset = offset % 32;
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
if (ScanCode)
|
|
||||||
fixed (int* c = Codes) { *(c + int_offset) |= 1 << bit_offset; }
|
|
||||||
else
|
|
||||||
fixed (int* k = Keys) { *(k + int_offset) |= 1 << bit_offset; }
|
fixed (int* k = Keys) { *(k + int_offset) |= 1 << bit_offset; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void DisableBit(int offset, bool ScanCode = false)
|
internal void DisableBit(int offset)
|
||||||
{
|
{
|
||||||
ValidateOffset(offset, ScanCode);
|
ValidateOffset(offset);
|
||||||
|
|
||||||
int int_offset = offset / 32;
|
int int_offset = offset / 32;
|
||||||
int bit_offset = offset % 32;
|
int bit_offset = offset % 32;
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
if (ScanCode)
|
|
||||||
fixed (int* c = Codes) { *(c + int_offset) &= ~(1 << bit_offset); }
|
|
||||||
else
|
|
||||||
fixed (int* k = Keys) { *(k + int_offset) &= ~(1 << bit_offset); }
|
fixed (int* k = Keys) { *(k + int_offset) &= ~(1 << bit_offset); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,12 +268,6 @@ namespace OpenTK.Input
|
||||||
for (int i = 0; i < NumInts; i++)
|
for (int i = 0; i < NumInts; i++)
|
||||||
*(k1 + i) |= *(k2 + i);
|
*(k1 + i) |= *(k2 + i);
|
||||||
}
|
}
|
||||||
int* c2 = other.Codes;
|
|
||||||
fixed (int* c1 = Codes)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < CodesSize; i++)
|
|
||||||
*(c1 + i) |= *(c2 + i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
IsConnected |= other.IsConnected;
|
IsConnected |= other.IsConnected;
|
||||||
}
|
}
|
||||||
|
@ -300,10 +281,10 @@ namespace OpenTK.Input
|
||||||
|
|
||||||
#region Private Members
|
#region Private Members
|
||||||
|
|
||||||
static void ValidateOffset(int offset, bool ScanCode)
|
static void ValidateOffset(int offset)
|
||||||
{
|
{
|
||||||
if (offset < 0 || offset >= (ScanCode ? 256 : NumInts * IntSize))
|
if (offset < 0 || offset >= NumInts * IntSize)
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -48,12 +48,8 @@ namespace OpenTK.Input
|
||||||
string description;
|
string description;
|
||||||
IntPtr id;
|
IntPtr id;
|
||||||
int numButtons, numWheels;
|
int numButtons, numWheels;
|
||||||
readonly bool[] button_state = new bool[Enum.GetValues(typeof(MouseButton)).Length];
|
|
||||||
float wheel, last_wheel;
|
MouseState state;
|
||||||
Point pos = new Point(), last_pos = new Point();
|
|
||||||
MouseMoveEventArgs move_args = new MouseMoveEventArgs();
|
|
||||||
MouseButtonEventArgs button_args = new MouseButtonEventArgs();
|
|
||||||
MouseWheelEventArgs wheel_args = new MouseWheelEventArgs();
|
|
||||||
#if COMPAT_REV1519
|
#if COMPAT_REV1519
|
||||||
int wheel_last_accessed = 0;
|
int wheel_last_accessed = 0;
|
||||||
Point pos_last_accessed = new Point();
|
Point pos_last_accessed = new Point();
|
||||||
|
@ -139,8 +135,7 @@ namespace OpenTK.Input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Wheel
|
public int Wheel
|
||||||
{
|
{
|
||||||
get { return (int)Math.Round(wheel, MidpointRounding.AwayFromZero); }
|
get { return state.Wheel; }
|
||||||
internal set { WheelPrecise = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -148,20 +143,7 @@ namespace OpenTK.Input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float WheelPrecise
|
public float WheelPrecise
|
||||||
{
|
{
|
||||||
get { return wheel; }
|
get { return state.WheelPrecise; }
|
||||||
internal set
|
|
||||||
{
|
|
||||||
wheel = value;
|
|
||||||
|
|
||||||
wheel_args.X = pos.X;
|
|
||||||
wheel_args.Y = pos.Y;
|
|
||||||
wheel_args.ValuePrecise = wheel;
|
|
||||||
wheel_args.DeltaPrecise = wheel - last_wheel;
|
|
||||||
|
|
||||||
WheelChanged(this, wheel_args);
|
|
||||||
|
|
||||||
last_wheel = wheel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -173,7 +155,7 @@ namespace OpenTK.Input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int X
|
public int X
|
||||||
{
|
{
|
||||||
get { return pos.X; }
|
get { return state.X; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -185,7 +167,7 @@ namespace OpenTK.Input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Y
|
public int Y
|
||||||
{
|
{
|
||||||
get { return pos.Y; }
|
get { return state.Y; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -201,21 +183,11 @@ namespace OpenTK.Input
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return button_state[(int)button];
|
return state[button];
|
||||||
}
|
}
|
||||||
internal set
|
internal set
|
||||||
{
|
{
|
||||||
bool previous_state = button_state[(int)button];
|
state[button] = value;
|
||||||
button_state[(int)button] = value;
|
|
||||||
|
|
||||||
button_args.X = pos.X;
|
|
||||||
button_args.Y = pos.Y;
|
|
||||||
button_args.Button = button;
|
|
||||||
button_args.IsPressed = value;
|
|
||||||
if (value && !previous_state)
|
|
||||||
ButtonDown(this, button_args);
|
|
||||||
else if (!value && previous_state)
|
|
||||||
ButtonUp(this, button_args);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,26 +197,29 @@ namespace OpenTK.Input
|
||||||
|
|
||||||
#region --- Internal Members ---
|
#region --- Internal Members ---
|
||||||
|
|
||||||
#region internal Point Position
|
internal void HandleMouseDown(object sender, MouseButtonEventArgs e)
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets a System.Drawing.Point representing the absolute position of the pointer, in window pixel coordinates.
|
|
||||||
/// </summary>
|
|
||||||
internal Point Position
|
|
||||||
{
|
{
|
||||||
set
|
state = e.Mouse;
|
||||||
{
|
ButtonDown(this, e);
|
||||||
pos = value;
|
|
||||||
move_args.X = pos.X;
|
|
||||||
move_args.Y = pos.Y;
|
|
||||||
move_args.XDelta = pos.X - last_pos.X;
|
|
||||||
move_args.YDelta = pos.Y - last_pos.Y;
|
|
||||||
Move(this, move_args);
|
|
||||||
last_pos = pos;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
internal void HandleMouseUp(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
state = e.Mouse;
|
||||||
|
ButtonUp(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void HandleMouseMove(object sender, MouseMoveEventArgs e)
|
||||||
|
{
|
||||||
|
state = e.Mouse;
|
||||||
|
Move(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void HandleMouseWheel(object sender, MouseWheelEventArgs e)
|
||||||
|
{
|
||||||
|
state = e.Mouse;
|
||||||
|
WheelChanged(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -309,8 +284,8 @@ namespace OpenTK.Input
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
int result = (int)Math.Round(wheel - wheel_last_accessed, MidpointRounding.AwayFromZero);
|
int result = (int)Math.Round(state.WheelPrecise - wheel_last_accessed, MidpointRounding.AwayFromZero);
|
||||||
wheel_last_accessed = (int)wheel;
|
wheel_last_accessed = state.Wheel;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,8 +302,8 @@ namespace OpenTK.Input
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
int result = pos.X - pos_last_accessed.X;
|
int result = state.X - pos_last_accessed.X;
|
||||||
pos_last_accessed.X = pos.X;
|
pos_last_accessed.X = state.X;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,8 +320,8 @@ namespace OpenTK.Input
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
int result = pos.Y - pos_last_accessed.Y;
|
int result = state.Y - pos_last_accessed.Y;
|
||||||
pos_last_accessed.Y = pos.Y;
|
pos_last_accessed.Y = state.Y;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,286 +332,4 @@ namespace OpenTK.Input
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event Arguments
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the event data for <see cref="MouseDevice"/> events.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// <para>
|
|
||||||
/// Do not cache instances of this type outside their event handler.
|
|
||||||
/// If necessary, you can clone an instance using the
|
|
||||||
/// <see cref="MouseEventArgs(MouseEventArgs)"/> constructor.
|
|
||||||
/// </para>
|
|
||||||
/// </remarks>
|
|
||||||
public class MouseEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new instance.
|
|
||||||
/// </summary>
|
|
||||||
public MouseEventArgs()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="x">The X position.</param>
|
|
||||||
/// <param name="y">The Y position.</param>
|
|
||||||
public MouseEventArgs(int x, int y)
|
|
||||||
{
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">The <see cref="MouseEventArgs"/> instance to clone.</param>
|
|
||||||
public MouseEventArgs(MouseEventArgs args)
|
|
||||||
: this(args.x, args.y)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Public Members
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the X position of the mouse for the event.
|
|
||||||
/// </summary>
|
|
||||||
public int X { get { return x; } internal set { x = value; } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Y position of the mouse for the event.
|
|
||||||
/// </summary>
|
|
||||||
public int Y { get { return y; } internal set { y = value; } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a System.Drawing.Points representing the location of the mouse for the event.
|
|
||||||
/// </summary>
|
|
||||||
public Point Position { get { return new Point(x, y); } }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the event data for <see cref="MouseDevice.Move"/> events.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// <para>
|
|
||||||
/// Do not cache instances of this type outside their event handler.
|
|
||||||
/// If necessary, you can clone an instance using the
|
|
||||||
/// <see cref="MouseMoveEventArgs(MouseMoveEventArgs)"/> constructor.
|
|
||||||
/// </para>
|
|
||||||
/// </remarks>
|
|
||||||
public class MouseMoveEventArgs : MouseEventArgs
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
int x_delta, y_delta;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
public MouseMoveEventArgs() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="x">The X position.</param>
|
|
||||||
/// <param name="y">The Y position.</param>
|
|
||||||
/// <param name="xDelta">The change in X position produced by this event.</param>
|
|
||||||
/// <param name="yDelta">The change in Y position produced by this event.</param>
|
|
||||||
public MouseMoveEventArgs(int x, int y, int xDelta, int yDelta)
|
|
||||||
: base(x, y)
|
|
||||||
{
|
|
||||||
XDelta = xDelta;
|
|
||||||
YDelta = yDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">The <see cref="MouseMoveEventArgs"/> instance to clone.</param>
|
|
||||||
public MouseMoveEventArgs(MouseMoveEventArgs args)
|
|
||||||
: this(args.X, args.Y, args.XDelta, args.YDelta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Public Members
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the change in X position produced by this event.
|
|
||||||
/// </summary>
|
|
||||||
public int XDelta { get { return x_delta; } internal set { x_delta = value; } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the change in Y position produced by this event.
|
|
||||||
/// </summary>
|
|
||||||
public int YDelta { get { return y_delta; } internal set { y_delta = value; } }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the event data for <see cref="MouseDevice.ButtonDown"/> and <see cref="MouseDevice.ButtonUp"/> events.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// <para>
|
|
||||||
/// Do not cache instances of this type outside their event handler.
|
|
||||||
/// If necessary, you can clone an instance using the
|
|
||||||
/// <see cref="MouseButtonEventArgs(MouseButtonEventArgs)"/> constructor.
|
|
||||||
/// </para>
|
|
||||||
/// </remarks>
|
|
||||||
public class MouseButtonEventArgs : MouseEventArgs
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
MouseButton button;
|
|
||||||
bool pressed;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
public MouseButtonEventArgs() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="x">The X position.</param>
|
|
||||||
/// <param name="y">The Y position.</param>
|
|
||||||
/// <param name="button">The mouse button for the event.</param>
|
|
||||||
/// <param name="pressed">The current state of the button.</param>
|
|
||||||
public MouseButtonEventArgs(int x, int y, MouseButton button, bool pressed)
|
|
||||||
: base(x, y)
|
|
||||||
{
|
|
||||||
this.button = button;
|
|
||||||
this.pressed = pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">The <see cref="MouseButtonEventArgs"/> instance to clone.</param>
|
|
||||||
public MouseButtonEventArgs(MouseButtonEventArgs args)
|
|
||||||
: this(args.X, args.Y, args.Button, args.IsPressed)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Public Members
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The mouse button for the event.
|
|
||||||
/// </summary>
|
|
||||||
public MouseButton Button { get { return button; } internal set { button = value; } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a System.Boolean representing the state of the mouse button for the event.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsPressed { get { return pressed; } internal set { pressed = value; } }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines the event data for <see cref="MouseDevice.WheelChanged"/> events.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// <para>
|
|
||||||
/// Do not cache instances of this type outside their event handler.
|
|
||||||
/// If necessary, you can clone an instance using the
|
|
||||||
/// <see cref="MouseWheelEventArgs(MouseWheelEventArgs)"/> constructor.
|
|
||||||
/// </para>
|
|
||||||
/// </remarks>
|
|
||||||
public class MouseWheelEventArgs : MouseEventArgs
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
float value;
|
|
||||||
float delta;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
public MouseWheelEventArgs() { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="x">The X position.</param>
|
|
||||||
/// <param name="y">The Y position.</param>
|
|
||||||
/// <param name="value">The value of the wheel.</param>
|
|
||||||
/// <param name="delta">The change in value of the wheel for this event.</param>
|
|
||||||
public MouseWheelEventArgs(int x, int y, int value, int delta)
|
|
||||||
: base(x, y)
|
|
||||||
{
|
|
||||||
this.value = value;
|
|
||||||
this.delta = delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="args">The <see cref="MouseWheelEventArgs"/> instance to clone.</param>
|
|
||||||
public MouseWheelEventArgs(MouseWheelEventArgs args)
|
|
||||||
: this(args.X, args.Y, args.Value, args.Delta)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Public Members
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the value of the wheel in integer units.
|
|
||||||
/// To support high-precision mice, it is recommended to use <see cref="ValuePrecise"/> instead.
|
|
||||||
/// </summary>
|
|
||||||
public int Value { get { return (int)Math.Round(value, MidpointRounding.AwayFromZero); } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the change in value of the wheel for this event in integer units.
|
|
||||||
/// To support high-precision mice, it is recommended to use <see cref="DeltaPrecise"/> instead.
|
|
||||||
/// </summary>
|
|
||||||
public int Delta { get { return (int)Math.Round(delta, MidpointRounding.AwayFromZero); } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the precise value of the wheel in floating-point units.
|
|
||||||
/// </summary>
|
|
||||||
public float ValuePrecise { get { return value; } internal set { this.value = value; } }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the precise change in value of the wheel for this event in floating-point units.
|
|
||||||
/// </summary>
|
|
||||||
public float DeltaPrecise { get { return delta; } internal set { delta = value; } }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
|
369
Source/OpenTK/Input/MouseEventArgs.cs
Normal file
369
Source/OpenTK/Input/MouseEventArgs.cs
Normal file
|
@ -0,0 +1,369 @@
|
||||||
|
#region License
|
||||||
|
//
|
||||||
|
// MouseEventArgs.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;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
namespace OpenTK.Input
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the event data for <see cref="MouseDevice"/> events.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Do not cache instances of this type outside their event handler.
|
||||||
|
/// If necessary, you can clone an instance using the
|
||||||
|
/// <see cref="MouseEventArgs(MouseEventArgs)"/> constructor.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public class MouseEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
MouseState state;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance.
|
||||||
|
/// </summary>
|
||||||
|
public MouseEventArgs()
|
||||||
|
{
|
||||||
|
state.SetIsConnected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The X position.</param>
|
||||||
|
/// <param name="y">The Y position.</param>
|
||||||
|
public MouseEventArgs(int x, int y)
|
||||||
|
: this()
|
||||||
|
{
|
||||||
|
state.X = x;
|
||||||
|
state.Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">The <see cref="MouseEventArgs"/> instance to clone.</param>
|
||||||
|
public MouseEventArgs(MouseEventArgs args)
|
||||||
|
: this(args.X, args.Y)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Protected Members
|
||||||
|
|
||||||
|
internal void SetButton(MouseButton button, ButtonState state)
|
||||||
|
{
|
||||||
|
if (button < 0 || button > MouseButton.LastButton)
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case ButtonState.Pressed:
|
||||||
|
this.state.EnableBit((int)button);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ButtonState.Released:
|
||||||
|
this.state.DisableBit((int)button);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal ButtonState GetButton(MouseButton button)
|
||||||
|
{
|
||||||
|
if (button < 0 || button > MouseButton.LastButton)
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
|
||||||
|
return
|
||||||
|
state.ReadBit((int)button) ?
|
||||||
|
ButtonState.Pressed : ButtonState.Released;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the X position of the mouse for the event.
|
||||||
|
/// </summary>
|
||||||
|
public int X { get { return state.X; } internal set { state.X = value; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Y position of the mouse for the event.
|
||||||
|
/// </summary>
|
||||||
|
public int Y { get { return state.Y; } internal set { state.Y = value; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="System.Drawing.Point"/> representing the location of the mouse for the event.
|
||||||
|
/// </summary>
|
||||||
|
public Point Position
|
||||||
|
{
|
||||||
|
get { return new Point(state.X, state.Y); }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
X = value.X;
|
||||||
|
Y = value.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current <see cref="OpenTK.Input.MouseState"/>.
|
||||||
|
/// </summary>
|
||||||
|
public MouseState Mouse
|
||||||
|
{
|
||||||
|
get { return state; }
|
||||||
|
internal set { state = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the event data for <see cref="MouseDevice.Move"/> events.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Do not cache instances of this type outside their event handler.
|
||||||
|
/// If necessary, you can clone an instance using the
|
||||||
|
/// <see cref="MouseMoveEventArgs(MouseMoveEventArgs)"/> constructor.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public class MouseMoveEventArgs : MouseEventArgs
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
int x_delta, y_delta;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
public MouseMoveEventArgs() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The X position.</param>
|
||||||
|
/// <param name="y">The Y position.</param>
|
||||||
|
/// <param name="xDelta">The change in X position produced by this event.</param>
|
||||||
|
/// <param name="yDelta">The change in Y position produced by this event.</param>
|
||||||
|
public MouseMoveEventArgs(int x, int y, int xDelta, int yDelta)
|
||||||
|
: base(x, y)
|
||||||
|
{
|
||||||
|
XDelta = xDelta;
|
||||||
|
YDelta = yDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseMoveEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">The <see cref="MouseMoveEventArgs"/> instance to clone.</param>
|
||||||
|
public MouseMoveEventArgs(MouseMoveEventArgs args)
|
||||||
|
: this(args.X, args.Y, args.XDelta, args.YDelta)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the change in X position produced by this event.
|
||||||
|
/// </summary>
|
||||||
|
public int XDelta { get { return x_delta; } internal set { x_delta = value; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the change in Y position produced by this event.
|
||||||
|
/// </summary>
|
||||||
|
public int YDelta { get { return y_delta; } internal set { y_delta = value; } }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the event data for <see cref="MouseDevice.ButtonDown"/> and <see cref="MouseDevice.ButtonUp"/> events.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Do not cache instances of this type outside their event handler.
|
||||||
|
/// If necessary, you can clone an instance using the
|
||||||
|
/// <see cref="MouseButtonEventArgs(MouseButtonEventArgs)"/> constructor.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public class MouseButtonEventArgs : MouseEventArgs
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
MouseButton button;
|
||||||
|
bool pressed;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
public MouseButtonEventArgs() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The X position.</param>
|
||||||
|
/// <param name="y">The Y position.</param>
|
||||||
|
/// <param name="button">The mouse button for the event.</param>
|
||||||
|
/// <param name="pressed">The current state of the button.</param>
|
||||||
|
public MouseButtonEventArgs(int x, int y, MouseButton button, bool pressed)
|
||||||
|
: base(x, y)
|
||||||
|
{
|
||||||
|
this.button = button;
|
||||||
|
this.pressed = pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseButtonEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">The <see cref="MouseButtonEventArgs"/> instance to clone.</param>
|
||||||
|
public MouseButtonEventArgs(MouseButtonEventArgs args)
|
||||||
|
: this(args.X, args.Y, args.Button, args.IsPressed)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="MouseButton"/> that triggered this event.
|
||||||
|
/// </summary>
|
||||||
|
public MouseButton Button { get { return button; } internal set { button = value; } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a System.Boolean representing the state of the mouse button for the event.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsPressed
|
||||||
|
{
|
||||||
|
get { return GetButton(Button) == ButtonState.Pressed; }
|
||||||
|
internal set { SetButton(Button, value ? ButtonState.Pressed : ButtonState.Released); }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the event data for <see cref="MouseDevice.WheelChanged"/> events.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>
|
||||||
|
/// Do not cache instances of this type outside their event handler.
|
||||||
|
/// If necessary, you can clone an instance using the
|
||||||
|
/// <see cref="MouseWheelEventArgs(MouseWheelEventArgs)"/> constructor.
|
||||||
|
/// </para>
|
||||||
|
/// </remarks>
|
||||||
|
public class MouseWheelEventArgs : MouseEventArgs
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
float delta;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
public MouseWheelEventArgs() { }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">The X position.</param>
|
||||||
|
/// <param name="y">The Y position.</param>
|
||||||
|
/// <param name="value">The value of the wheel.</param>
|
||||||
|
/// <param name="delta">The change in value of the wheel for this event.</param>
|
||||||
|
public MouseWheelEventArgs(int x, int y, int value, int delta)
|
||||||
|
: base(x, y)
|
||||||
|
{
|
||||||
|
Mouse.SetScrollAbsolute(Mouse.Scroll.X, value);
|
||||||
|
this.delta = delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new <see cref="MouseWheelEventArgs"/> instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">The <see cref="MouseWheelEventArgs"/> instance to clone.</param>
|
||||||
|
public MouseWheelEventArgs(MouseWheelEventArgs args)
|
||||||
|
: this(args.X, args.Y, args.Value, args.Delta)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value of the wheel in integer units.
|
||||||
|
/// To support high-precision mice, it is recommended to use <see cref="ValuePrecise"/> instead.
|
||||||
|
/// </summary>
|
||||||
|
public int Value { get { return (int)Math.Round(Mouse.Scroll.Y, MidpointRounding.AwayFromZero); } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the change in value of the wheel for this event in integer units.
|
||||||
|
/// To support high-precision mice, it is recommended to use <see cref="DeltaPrecise"/> instead.
|
||||||
|
/// </summary>
|
||||||
|
public int Delta { get { return (int)Math.Round(delta, MidpointRounding.AwayFromZero); } }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the precise value of the wheel in floating-point units.
|
||||||
|
/// </summary>
|
||||||
|
public float ValuePrecise
|
||||||
|
{
|
||||||
|
get { return Mouse.Scroll.Y; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the precise change in value of the wheel for this event in floating-point units.
|
||||||
|
/// </summary>
|
||||||
|
public float DeltaPrecise { get { return delta; } internal set { delta = value; } }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
119
Source/OpenTK/Input/MouseScrollWheel.cs
Normal file
119
Source/OpenTK/Input/MouseScrollWheel.cs
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#region License
|
||||||
|
//
|
||||||
|
// MouseWheel.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.Input
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the state of a mouse wheel.
|
||||||
|
/// </summary>
|
||||||
|
public struct MouseScrollWheel : IEquatable<MouseScrollWheel>
|
||||||
|
{
|
||||||
|
#region Public Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the absolute horizontal offset of the wheel,
|
||||||
|
/// or 0 if no horizontal scroll wheel exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The x.</value>
|
||||||
|
public float X { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the absolute vertical offset of the wheel,
|
||||||
|
/// or 0 if no vertical scroll wheel exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The y.</value>
|
||||||
|
public float Y { get; internal set; }
|
||||||
|
|
||||||
|
/// <param name="left">A <see cref="MouseScrollWheel"/> instance to test for equality.</param>
|
||||||
|
/// <param name="right">A <see cref="MouseScrollWheel"/> instance to test for equality.</param>
|
||||||
|
public static bool operator ==(MouseScrollWheel left, MouseScrollWheel right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <param name="left">A <see cref="MouseScrollWheel"/> instance to test for inequality.</param>
|
||||||
|
/// <param name="right">A <see cref="MouseScrollWheel"/> instance to test for inequality.</param>
|
||||||
|
public static bool operator !=(MouseScrollWheel left, MouseScrollWheel right)
|
||||||
|
{
|
||||||
|
return !left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return string.Format("[X={0:0.00}, Y={1:0.00}]", X, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serves as a hash function for a <see cref="OpenTK.Input.MouseScrollWheel"/> object.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
|
||||||
|
/// hash table.</returns>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return X.GetHashCode() ^ Y.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</param>
|
||||||
|
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
|
||||||
|
/// <see cref="OpenTK.Input.MouseScrollWheel"/>; otherwise, <c>false</c>.</returns>
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
obj is MouseScrollWheel &&
|
||||||
|
Equals((MouseScrollWheel)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IEquatable Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the specified <see cref="OpenTK.Input.MouseScrollWheel"/> is equal to the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="other">The <see cref="OpenTK.Input.MouseScrollWheel"/> to compare with the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</param>
|
||||||
|
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.MouseScrollWheel"/> is equal to the current
|
||||||
|
/// <see cref="OpenTK.Input.MouseScrollWheel"/>; otherwise, <c>false</c>.</returns>
|
||||||
|
public bool Equals(MouseScrollWheel other)
|
||||||
|
{
|
||||||
|
return X == other.X && Y == other.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -38,13 +38,9 @@ namespace OpenTK.Input
|
||||||
{
|
{
|
||||||
#region Fields
|
#region Fields
|
||||||
|
|
||||||
// Allocate enough ints to store all mouse buttons
|
|
||||||
const int IntSize = sizeof(int);
|
|
||||||
const int NumInts = ((int)MouseButton.LastButton + IntSize - 1) / IntSize;
|
|
||||||
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
|
|
||||||
unsafe fixed int Buttons[NumInts];
|
|
||||||
int x, y;
|
int x, y;
|
||||||
float wheel;
|
MouseScrollWheel scroll;
|
||||||
|
ushort buttons;
|
||||||
bool is_connected;
|
bool is_connected;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -93,7 +89,7 @@ namespace OpenTK.Input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Wheel
|
public int Wheel
|
||||||
{
|
{
|
||||||
get { return (int)Math.Round(wheel, MidpointRounding.AwayFromZero); }
|
get { return (int)Math.Round(scroll.Y, MidpointRounding.AwayFromZero); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -101,11 +97,16 @@ namespace OpenTK.Input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float WheelPrecise
|
public float WheelPrecise
|
||||||
{
|
{
|
||||||
get { return wheel; }
|
get { return scroll.Y; }
|
||||||
internal set
|
|
||||||
{
|
|
||||||
wheel = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a <see cref="OpenTK.Input.MouseScrollWheel"/> instance,
|
||||||
|
/// representing the current state of the mouse scroll wheel.
|
||||||
|
/// </summary>
|
||||||
|
public MouseScrollWheel Scroll
|
||||||
|
{
|
||||||
|
get { return scroll; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -253,13 +254,18 @@ namespace OpenTK.Input
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
unsafe
|
return buttons.GetHashCode() ^ X.GetHashCode() ^ Y.GetHashCode() ^ scroll.GetHashCode();
|
||||||
{
|
|
||||||
fixed (int* b = Buttons)
|
|
||||||
{
|
|
||||||
return b->GetHashCode() ^ X.GetHashCode() ^ Y.GetHashCode() ^ WheelPrecise.GetHashCode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseState"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseState"/>.</returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
string b = Convert.ToString(buttons, 2).PadLeft(10, '0');
|
||||||
|
return String.Format("[MouseState: X={0}, Y={1}, Scroll={2}, Buttons={3}, IsConnected={4}]",
|
||||||
|
X, Y, Scroll, b, IsConnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -269,78 +275,58 @@ namespace OpenTK.Input
|
||||||
internal bool ReadBit(int offset)
|
internal bool ReadBit(int offset)
|
||||||
{
|
{
|
||||||
ValidateOffset(offset);
|
ValidateOffset(offset);
|
||||||
|
return (buttons & (1 << offset)) != 0;
|
||||||
int int_offset = offset / 32;
|
|
||||||
int bit_offset = offset % 32;
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
fixed (int* b = Buttons)
|
|
||||||
{
|
|
||||||
return (*(b + int_offset) & (1 << bit_offset)) != 0u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void EnableBit(int offset)
|
internal void EnableBit(int offset)
|
||||||
{
|
{
|
||||||
ValidateOffset(offset);
|
ValidateOffset(offset);
|
||||||
|
buttons |= unchecked((ushort)(1 << offset));
|
||||||
int int_offset = offset / 32;
|
|
||||||
int bit_offset = offset % 32;
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
fixed (int* b = Buttons)
|
|
||||||
{
|
|
||||||
*(b + int_offset) |= 1 << bit_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void DisableBit(int offset)
|
internal void DisableBit(int offset)
|
||||||
{
|
{
|
||||||
ValidateOffset(offset);
|
ValidateOffset(offset);
|
||||||
|
buttons &= unchecked((ushort)(~(1 << offset)));
|
||||||
int int_offset = offset / 32;
|
|
||||||
int bit_offset = offset % 32;
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
fixed (int* b = Buttons)
|
|
||||||
{
|
|
||||||
*(b + int_offset) &= ~(1 << bit_offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void MergeBits(MouseState other)
|
internal void MergeBits(MouseState other)
|
||||||
{
|
{
|
||||||
unsafe
|
buttons |= other.buttons;
|
||||||
{
|
SetScrollRelative(other.scroll.X, other.scroll.Y);
|
||||||
int* b2 = other.Buttons;
|
|
||||||
fixed (int* b1 = Buttons)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < NumInts; i++)
|
|
||||||
*(b1 + i) |= *(b2 + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
WheelPrecise += other.WheelPrecise;
|
|
||||||
X += other.X;
|
X += other.X;
|
||||||
Y += other.Y;
|
Y += other.Y;
|
||||||
IsConnected |= other.IsConnected;
|
IsConnected |= other.IsConnected;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
internal void SetIsConnected(bool value)
|
internal void SetIsConnected(bool value)
|
||||||
{
|
{
|
||||||
IsConnected = value;
|
IsConnected = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Internal Members
|
||||||
|
|
||||||
|
internal void SetScrollAbsolute(float x, float y)
|
||||||
|
{
|
||||||
|
scroll.X = x;
|
||||||
|
scroll.Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetScrollRelative(float x, float y)
|
||||||
|
{
|
||||||
|
scroll.X += x;
|
||||||
|
scroll.Y += y;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Members
|
#region Private Members
|
||||||
|
|
||||||
static void ValidateOffset(int offset)
|
static void ValidateOffset(int offset)
|
||||||
{
|
{
|
||||||
if (offset < 0 || offset >= NumInts * IntSize)
|
if (offset < 0 || offset >= 16)
|
||||||
throw new ArgumentOutOfRangeException("offset");
|
throw new ArgumentOutOfRangeException("offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,18 +341,11 @@ namespace OpenTK.Input
|
||||||
/// <returns>True, if both instances are equal; false otherwise.</returns>
|
/// <returns>True, if both instances are equal; false otherwise.</returns>
|
||||||
public bool Equals(MouseState other)
|
public bool Equals(MouseState other)
|
||||||
{
|
{
|
||||||
bool equal = true;
|
return
|
||||||
unsafe
|
buttons == other.buttons &&
|
||||||
{
|
X == other.X &&
|
||||||
int* b2 = other.Buttons;
|
Y == other.Y &&
|
||||||
fixed (int* b1 = Buttons)
|
Scroll == other.Scroll;
|
||||||
{
|
|
||||||
for (int i = 0; equal && i < NumInts; i++)
|
|
||||||
equal &= *(b1 + i) == *(b2 + i);
|
|
||||||
}
|
|
||||||
equal &= X == other.X && Y == other.Y && WheelPrecise == other.WheelPrecise;
|
|
||||||
}
|
|
||||||
return equal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -163,12 +163,7 @@ namespace OpenTK
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public Point PointToScreen(Point point)
|
public Point PointToScreen(Point point)
|
||||||
{
|
{
|
||||||
// Here we use the fact that PointToClient just translates the point, and PointToScreen
|
return implementation.PointToScreen(point);
|
||||||
// should perform the inverse operation.
|
|
||||||
Point trans = PointToClient(Point.Empty);
|
|
||||||
point.X -= trans.X;
|
|
||||||
point.Y -= trans.Y;
|
|
||||||
return point;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -680,6 +675,26 @@ namespace OpenTK
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<EventArgs> WindowStateChanged = delegate { };
|
public event EventHandler<EventArgs> WindowStateChanged = delegate { };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a <see cref="MouseButton"/> is pressed.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<MouseButtonEventArgs> MouseDown = delegate { };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a <see cref="MouseButton"/> is released.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<MouseButtonEventArgs> MouseUp = delegate { };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs whenever the mouse is moved.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<MouseMoveEventArgs> MouseMove = delegate { };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs whenever a mouse wheel is moved;
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<MouseWheelEventArgs> MouseWheel = delegate { };
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -902,6 +917,54 @@ namespace OpenTK
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="MouseDown"/> event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">
|
||||||
|
/// A <see cref="MouseButtonEventArgs"/> instance carrying mouse state information.
|
||||||
|
/// The information carried by this instance is only valid within this method body.
|
||||||
|
/// </param>
|
||||||
|
protected virtual void OnMouseDown(MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
MouseDown(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="MouseUp"/> event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">
|
||||||
|
/// A <see cref="MouseButtonEventArgs"/> instance carrying mouse state information.
|
||||||
|
/// The information carried by this instance is only valid within this method body.
|
||||||
|
/// </param>
|
||||||
|
protected virtual void OnMouseUp(MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
MouseUp(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="MouseMove"/> event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">
|
||||||
|
/// A <see cref="MouseMoveEventArgs"/> instance carrying mouse state information.
|
||||||
|
/// The information carried by this instance is only valid within this method body.
|
||||||
|
/// </param>
|
||||||
|
protected virtual void OnMouseMove(MouseMoveEventArgs e)
|
||||||
|
{
|
||||||
|
MouseMove(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the <see cref="MouseWheel"/> event.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">
|
||||||
|
/// A <see cref="MouseWheelEventArgs"/> instance carrying mouse state information.
|
||||||
|
/// The information carried by this instance is only valid within this method body.
|
||||||
|
/// </param>
|
||||||
|
protected virtual void OnMouseWheel(MouseWheelEventArgs e)
|
||||||
|
{
|
||||||
|
MouseWheel(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
#region OnResize
|
#region OnResize
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1054,6 +1117,11 @@ namespace OpenTK
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private void OnMouseDownInternal(object sender, MouseButtonEventArgs e) { OnMouseDown(e); }
|
||||||
|
private void OnMouseUpInternal(object sender, MouseButtonEventArgs e) { OnMouseUp(e); }
|
||||||
|
private void OnMouseMoveInternal(object sender, MouseMoveEventArgs e) { OnMouseMove(e); }
|
||||||
|
private void OnMouseWheelInternal(object sender, MouseWheelEventArgs e) { OnMouseWheel(e); }
|
||||||
|
|
||||||
#region OnMoveInternal
|
#region OnMoveInternal
|
||||||
|
|
||||||
private void OnMoveInternal(object sender, EventArgs e) { OnMove(e); }
|
private void OnMoveInternal(object sender, EventArgs e) { OnMove(e); }
|
||||||
|
@ -1116,6 +1184,10 @@ namespace OpenTK
|
||||||
implementation.KeyUp += OnKeyUpInternal;
|
implementation.KeyUp += OnKeyUpInternal;
|
||||||
implementation.MouseEnter += OnMouseEnterInternal;
|
implementation.MouseEnter += OnMouseEnterInternal;
|
||||||
implementation.MouseLeave += OnMouseLeaveInternal;
|
implementation.MouseLeave += OnMouseLeaveInternal;
|
||||||
|
implementation.MouseDown += OnMouseDownInternal;
|
||||||
|
implementation.MouseUp += OnMouseUpInternal;
|
||||||
|
implementation.MouseMove += OnMouseMoveInternal;
|
||||||
|
implementation.MouseWheel += OnMouseWheelInternal;
|
||||||
implementation.Move += OnMoveInternal;
|
implementation.Move += OnMoveInternal;
|
||||||
implementation.Resize += OnResizeInternal;
|
implementation.Resize += OnResizeInternal;
|
||||||
implementation.TitleChanged += OnTitleChangedInternal;
|
implementation.TitleChanged += OnTitleChangedInternal;
|
||||||
|
@ -1136,6 +1208,10 @@ namespace OpenTK
|
||||||
implementation.KeyUp -= OnKeyUpInternal;
|
implementation.KeyUp -= OnKeyUpInternal;
|
||||||
implementation.MouseEnter -= OnMouseEnterInternal;
|
implementation.MouseEnter -= OnMouseEnterInternal;
|
||||||
implementation.MouseLeave -= OnMouseLeaveInternal;
|
implementation.MouseLeave -= OnMouseLeaveInternal;
|
||||||
|
implementation.MouseDown -= OnMouseDownInternal;
|
||||||
|
implementation.MouseUp -= OnMouseUpInternal;
|
||||||
|
implementation.MouseMove -= OnMouseMoveInternal;
|
||||||
|
implementation.MouseWheel -= OnMouseWheelInternal;
|
||||||
implementation.Move -= OnMoveInternal;
|
implementation.Move -= OnMoveInternal;
|
||||||
implementation.Resize -= OnResizeInternal;
|
implementation.Resize -= OnResizeInternal;
|
||||||
implementation.TitleChanged -= OnTitleChangedInternal;
|
implementation.TitleChanged -= OnTitleChangedInternal;
|
||||||
|
|
|
@ -366,9 +366,6 @@
|
||||||
<Compile Include="Platform\X11\Structs.cs">
|
<Compile Include="Platform\X11\Structs.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Platform\X11\X11Input.cs">
|
|
||||||
<SubType>Code</SubType>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Platform\X11\X11Factory.cs">
|
<Compile Include="Platform\X11\X11Factory.cs">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
@ -797,6 +794,9 @@
|
||||||
<Compile Include="Platform\MacOS\Carbon\Cgl.cs" />
|
<Compile Include="Platform\MacOS\Carbon\Cgl.cs" />
|
||||||
<Compile Include="WindowIcon.cs" />
|
<Compile Include="WindowIcon.cs" />
|
||||||
<Compile Include="Platform\MacOS\Cocoa\NSBitmapFormat.cs" />
|
<Compile Include="Platform\MacOS\Cocoa\NSBitmapFormat.cs" />
|
||||||
|
<Compile Include="Platform\NativeWindowBase.cs" />
|
||||||
|
<Compile Include="Input\MouseScrollWheel.cs" />
|
||||||
|
<Compile Include="Input\MouseEventArgs.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -42,18 +42,33 @@ namespace OpenTK.Platform
|
||||||
|
|
||||||
readonly LegacyJoystickDriver JoystickDriver = new LegacyJoystickDriver();
|
readonly LegacyJoystickDriver JoystickDriver = new LegacyJoystickDriver();
|
||||||
|
|
||||||
internal LegacyInputDriver()
|
internal LegacyInputDriver(INativeWindow window)
|
||||||
{
|
{
|
||||||
dummy_mice_list.Add(new MouseDevice());
|
if (window == null)
|
||||||
Mouse[0].Description = "Standard Mouse";
|
throw new ArgumentNullException();
|
||||||
Mouse[0].NumberOfButtons = 3;
|
|
||||||
Mouse[0].NumberOfWheels = 1;
|
|
||||||
|
|
||||||
dummy_keyboard_list.Add(new KeyboardDevice());
|
var mouse = new MouseDevice();
|
||||||
Keyboard[0].Description = "Standard Keyboard";
|
mouse.Description = "Standard Mouse";
|
||||||
Keyboard[0].NumberOfKeys = 101;
|
mouse.NumberOfButtons = 3;
|
||||||
Keyboard[0].NumberOfLeds = 3;
|
mouse.NumberOfWheels = 1;
|
||||||
Keyboard[0].NumberOfFunctionKeys = 12;
|
dummy_mice_list.Add(mouse);
|
||||||
|
|
||||||
|
var keyboard = new KeyboardDevice();
|
||||||
|
keyboard.Description = "Standard Keyboard";
|
||||||
|
keyboard.NumberOfKeys = 101;
|
||||||
|
keyboard.NumberOfLeds = 3;
|
||||||
|
keyboard.NumberOfFunctionKeys = 12;
|
||||||
|
dummy_keyboard_list.Add(keyboard);
|
||||||
|
|
||||||
|
// Hook mouse events
|
||||||
|
window.MouseDown += mouse.HandleMouseDown;
|
||||||
|
window.MouseUp += mouse.HandleMouseUp;
|
||||||
|
window.MouseMove += mouse.HandleMouseMove;
|
||||||
|
window.MouseWheel += mouse.HandleMouseWheel;
|
||||||
|
|
||||||
|
// Hook keyboard events
|
||||||
|
window.KeyDown += keyboard.HandleKeyDown;
|
||||||
|
window.KeyUp += keyboard.HandleKeyUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IInputDriver Members
|
#region IInputDriver Members
|
||||||
|
|
|
@ -29,7 +29,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace OpenTK.Platform.MacOS.Carbon
|
namespace OpenTK.Platform.MacOS
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// http://web.archive.org/web/20100501161453/http://www.classicteck.com/rbarticles/mackeyboard.php
|
// http://web.archive.org/web/20100501161453/http://www.classicteck.com/rbarticles/mackeyboard.php
|
||||||
|
|
|
@ -35,6 +35,11 @@ namespace OpenTK.Platform.MacOS
|
||||||
{
|
{
|
||||||
static class Class
|
static class Class
|
||||||
{
|
{
|
||||||
|
public static readonly IntPtr NSAutoreleasePool = Get("NSAutoreleasePool");
|
||||||
|
public static readonly IntPtr NSDictionary = Get("NSDictionary");
|
||||||
|
public static readonly IntPtr NSNumber = Get("NSNumber");
|
||||||
|
public static readonly IntPtr NSUserDefaults = Get("NSUserDefaults");
|
||||||
|
|
||||||
[DllImport (Cocoa.LibObjC)]
|
[DllImport (Cocoa.LibObjC)]
|
||||||
extern static IntPtr class_getName(IntPtr handle);
|
extern static IntPtr class_getName(IntPtr handle);
|
||||||
|
|
||||||
|
|
|
@ -57,9 +57,15 @@ namespace OpenTK.Platform.MacOS
|
||||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2, IntPtr intPtr3);
|
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2, IntPtr intPtr3);
|
||||||
|
|
||||||
|
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||||
|
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2, IntPtr intPtr3, IntPtr intPtr4, IntPtr intPtr5);
|
||||||
|
|
||||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr p1, PointF p2);
|
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr p1, PointF p2);
|
||||||
|
|
||||||
|
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||||
|
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, bool p1);
|
||||||
|
|
||||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, SizeF p1);
|
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, SizeF p1);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
internal static void Initialize()
|
internal static void Initialize()
|
||||||
{
|
{
|
||||||
// Create the NSAutoreleasePool
|
// Create the NSAutoreleasePool
|
||||||
AutoreleasePool = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSAutoreleasePool"), Selector.Alloc), Selector.Init);
|
AutoreleasePool = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.NSAutoreleasePool, Selector.Alloc), Selector.Init);
|
||||||
|
|
||||||
// Register a Quit method to be called on cmd-q
|
// Register a Quit method to be called on cmd-q
|
||||||
IntPtr nsapp = Class.Get("NSApplication");
|
IntPtr nsapp = Class.Get("NSApplication");
|
||||||
|
@ -80,6 +80,23 @@ namespace OpenTK.Platform.MacOS
|
||||||
|
|
||||||
// Tell cocoa we're ready to run the application (usually called by [NSApp run]).
|
// Tell cocoa we're ready to run the application (usually called by [NSApp run]).
|
||||||
Cocoa.SendVoid(Handle, Selector.Get("finishLaunching"));
|
Cocoa.SendVoid(Handle, Selector.Get("finishLaunching"));
|
||||||
|
|
||||||
|
// Disable momentum scrolling and long-press key pop-ups
|
||||||
|
IntPtr settings = Cocoa.SendIntPtr(Class.NSDictionary, Selector.Alloc);
|
||||||
|
IntPtr momentum_scrolling = Cocoa.SendIntPtr(Class.NSNumber, Selector.Get("numberWithBool:"), false);
|
||||||
|
IntPtr press_and_hold = Cocoa.SendIntPtr(Class.NSNumber, Selector.Get("numberWithBool:"), false);
|
||||||
|
|
||||||
|
// Initialize and register the settings dictionary
|
||||||
|
settings =
|
||||||
|
Cocoa.SendIntPtr(settings, Selector.Get("initWithObjectsAndKeys:"),
|
||||||
|
momentum_scrolling, Cocoa.ToNSString("AppleMomentumScrollSupported"),
|
||||||
|
press_and_hold, Cocoa.ToNSString("ApplePressAndHoldEnabled"),
|
||||||
|
IntPtr.Zero);
|
||||||
|
Cocoa.SendVoid(
|
||||||
|
Cocoa.SendIntPtr(Class.NSUserDefaults, Selector.Get("standardUserDefaults")),
|
||||||
|
Selector.Get("registerDefaults:"),
|
||||||
|
settings);
|
||||||
|
Cocoa.SendVoid(settings, Selector.Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static event EventHandler<CancelEventArgs> Quit = delegate { };
|
internal static event EventHandler<CancelEventArgs> Quit = delegate { };
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#region License
|
#region License
|
||||||
//
|
//
|
||||||
// CocoaNativeWindow.cs
|
// CocoaNativeWindow.cs
|
||||||
//
|
//
|
||||||
|
@ -38,30 +38,14 @@ using OpenTK.Input;
|
||||||
|
|
||||||
namespace OpenTK.Platform.MacOS
|
namespace OpenTK.Platform.MacOS
|
||||||
{
|
{
|
||||||
class CocoaNativeWindow : INativeWindow
|
class CocoaNativeWindow : NativeWindowBase
|
||||||
{
|
{
|
||||||
static int UniqueId;
|
static int UniqueId;
|
||||||
|
|
||||||
public event EventHandler<EventArgs> Move = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Resize = delegate { };
|
|
||||||
public event EventHandler<System.ComponentModel.CancelEventArgs> Closing = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Closed = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Disposed = delegate { };
|
|
||||||
public event EventHandler<EventArgs> IconChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> TitleChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> VisibleChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> FocusedChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> WindowBorderChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> WindowStateChanged = delegate { };
|
|
||||||
public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyDown = delegate { };
|
|
||||||
public event EventHandler<KeyPressEventArgs> KeyPress = delegate { };
|
|
||||||
public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyUp = delegate { };
|
|
||||||
public event EventHandler<EventArgs> MouseLeave = delegate { };
|
|
||||||
public event EventHandler<EventArgs> MouseEnter = delegate { };
|
|
||||||
|
|
||||||
static readonly IntPtr selNextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:");
|
static readonly IntPtr selNextEventMatchingMask = Selector.Get("nextEventMatchingMask:untilDate:inMode:dequeue:");
|
||||||
static readonly IntPtr selSendEvent = Selector.Get("sendEvent:");
|
static readonly IntPtr selSendEvent = Selector.Get("sendEvent:");
|
||||||
//static readonly IntPtr selUpdateWindows = Selector.Get("updateWindows");
|
//static readonly IntPtr selUpdateWindows = Selector.Get("updateWindows");
|
||||||
|
static readonly IntPtr selContentView = Selector.Get("contentView");
|
||||||
static readonly IntPtr selConvertRectFromScreen = Selector.Get("convertRectFromScreen:");
|
static readonly IntPtr selConvertRectFromScreen = Selector.Get("convertRectFromScreen:");
|
||||||
static readonly IntPtr selConvertRectToScreen = Selector.Get("convertRectToScreen:");
|
static readonly IntPtr selConvertRectToScreen = Selector.Get("convertRectToScreen:");
|
||||||
static readonly IntPtr selPerformClose = Selector.Get("performClose:");
|
static readonly IntPtr selPerformClose = Selector.Get("performClose:");
|
||||||
|
@ -94,7 +78,10 @@ namespace OpenTK.Platform.MacOS
|
||||||
static readonly IntPtr selLocationInWindowOwner = Selector.Get("locationInWindow");
|
static readonly IntPtr selLocationInWindowOwner = Selector.Get("locationInWindow");
|
||||||
static readonly IntPtr selHide = Selector.Get("hide");
|
static readonly IntPtr selHide = Selector.Get("hide");
|
||||||
static readonly IntPtr selUnhide = Selector.Get("unhide");
|
static readonly IntPtr selUnhide = Selector.Get("unhide");
|
||||||
|
static readonly IntPtr selScrollingDeltaX = Selector.Get("scrollingDeltaX");
|
||||||
static readonly IntPtr selScrollingDeltaY = Selector.Get("scrollingDeltaY");
|
static readonly IntPtr selScrollingDeltaY = Selector.Get("scrollingDeltaY");
|
||||||
|
static readonly IntPtr selDeltaX = Selector.Get("deltaX");
|
||||||
|
static readonly IntPtr selDeltaY = Selector.Get("deltaY");
|
||||||
static readonly IntPtr selButtonNumber = Selector.Get("buttonNumber");
|
static readonly IntPtr selButtonNumber = Selector.Get("buttonNumber");
|
||||||
static readonly IntPtr selSetStyleMask = Selector.Get("setStyleMask:");
|
static readonly IntPtr selSetStyleMask = Selector.Get("setStyleMask:");
|
||||||
static readonly IntPtr selStyleMask = Selector.Get("styleMask");
|
static readonly IntPtr selStyleMask = Selector.Get("styleMask");
|
||||||
|
@ -145,13 +132,10 @@ namespace OpenTK.Platform.MacOS
|
||||||
private bool exists;
|
private bool exists;
|
||||||
private bool cursorVisible = true;
|
private bool cursorVisible = true;
|
||||||
private System.Drawing.Icon icon;
|
private System.Drawing.Icon icon;
|
||||||
private LegacyInputDriver inputDriver = new LegacyInputDriver();
|
|
||||||
private WindowBorder windowBorder = WindowBorder.Resizable;
|
private WindowBorder windowBorder = WindowBorder.Resizable;
|
||||||
private Nullable<WindowBorder> deferredWindowBorder;
|
private Nullable<WindowBorder> deferredWindowBorder;
|
||||||
private Nullable<WindowBorder> previousWindowBorder;
|
private Nullable<WindowBorder> previousWindowBorder;
|
||||||
private WindowState windowState = WindowState.Normal;
|
private WindowState windowState = WindowState.Normal;
|
||||||
private OpenTK.Input.KeyboardKeyEventArgs keyArgs = new OpenTK.Input.KeyboardKeyEventArgs();
|
|
||||||
private KeyPressEventArgs keyPressArgs = new KeyPressEventArgs((char)0);
|
|
||||||
private string title;
|
private string title;
|
||||||
private RectangleF previousBounds;
|
private RectangleF previousBounds;
|
||||||
private int normalLevel;
|
private int normalLevel;
|
||||||
|
@ -160,7 +144,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
private bool cursorInsideWindow = true;
|
private bool cursorInsideWindow = true;
|
||||||
private MouseCursor selectedCursor = MouseCursor.Default; // user-selected cursor
|
private MouseCursor selectedCursor = MouseCursor.Default; // user-selected cursor
|
||||||
|
|
||||||
private const float scrollFactor = 120.0f;
|
private const float scrollFactor = 10.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)
|
||||||
|
@ -188,7 +172,17 @@ namespace OpenTK.Platform.MacOS
|
||||||
Class.RegisterClass(viewClass);
|
Class.RegisterClass(viewClass);
|
||||||
|
|
||||||
// Create window instance
|
// Create window instance
|
||||||
var contentRect = new System.Drawing.RectangleF(x, y, width, height);
|
// Note: The coordinate system of Cocoa places (0,0) at the bottom left.
|
||||||
|
// We need to get the height of the main screen and flip that in order
|
||||||
|
// to place the window at the correct position.
|
||||||
|
// Note: NSWindows are laid out relative to the main screen.
|
||||||
|
var screenRect =
|
||||||
|
Cocoa.SendRect(
|
||||||
|
Cocoa.SendIntPtr(
|
||||||
|
Cocoa.SendIntPtr(Class.Get("NSScreen"), Selector.Get("screens")),
|
||||||
|
Selector.Get("objectAtIndex:"), 0),
|
||||||
|
Selector.Get("frame"));
|
||||||
|
var contentRect = new System.Drawing.RectangleF(x, screenRect.Height - height - y, width, height);
|
||||||
var style = GetStyleMask(windowBorder);
|
var style = GetStyleMask(windowBorder);
|
||||||
var bufferingType = NSBackingStore.Buffered;
|
var bufferingType = NSBackingStore.Buffered;
|
||||||
|
|
||||||
|
@ -259,7 +253,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
GraphicsContext.CurrentContext.Update(windowInfo);
|
GraphicsContext.CurrentContext.Update(windowInfo);
|
||||||
|
|
||||||
if (suppressResize == 0)
|
if (suppressResize == 0)
|
||||||
Resize(this, EventArgs.Empty);
|
OnResize(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplicationQuit(object sender, CancelEventArgs e)
|
private void ApplicationQuit(object sender, CancelEventArgs e)
|
||||||
|
@ -272,17 +266,17 @@ namespace OpenTK.Platform.MacOS
|
||||||
{
|
{
|
||||||
// Problem: Called only when you stop moving for a brief moment,
|
// Problem: Called only when you stop moving for a brief moment,
|
||||||
// not each frame as it is on PC.
|
// not each frame as it is on PC.
|
||||||
Move(this, EventArgs.Empty);
|
OnMove(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindowDidBecomeKey(IntPtr self, IntPtr cmd, IntPtr notification)
|
private void WindowDidBecomeKey(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||||
{
|
{
|
||||||
FocusedChanged(this, EventArgs.Empty);
|
OnFocusedChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindowDidResignKey(IntPtr self, IntPtr cmd, IntPtr notification)
|
private void WindowDidResignKey(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||||
{
|
{
|
||||||
FocusedChanged(this, EventArgs.Empty);
|
OnFocusedChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindowWillMiniaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
private void WindowWillMiniaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||||
|
@ -296,14 +290,14 @@ namespace OpenTK.Platform.MacOS
|
||||||
private void WindowDidMiniaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
private void WindowDidMiniaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||||
{
|
{
|
||||||
windowState = WindowState.Minimized;
|
windowState = WindowState.Minimized;
|
||||||
WindowStateChanged(this, EventArgs.Empty);
|
OnWindowStateChanged(EventArgs.Empty);
|
||||||
OnResize(false); // Don't set tracking area when we minimize
|
OnResize(false); // Don't set tracking area when we minimize
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WindowDidDeminiaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
private void WindowDidDeminiaturize(IntPtr self, IntPtr cmd, IntPtr notification)
|
||||||
{
|
{
|
||||||
windowState = WindowState.Normal;
|
windowState = WindowState.Normal;
|
||||||
WindowStateChanged(this, EventArgs.Empty);
|
OnWindowStateChanged(EventArgs.Empty);
|
||||||
OnResize(true);
|
OnResize(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +315,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
InternalBounds = toFrame;
|
InternalBounds = toFrame;
|
||||||
windowState = WindowState.Maximized;
|
windowState = WindowState.Maximized;
|
||||||
|
|
||||||
WindowStateChanged(this, EventArgs.Empty);
|
OnWindowStateChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -329,11 +323,11 @@ namespace OpenTK.Platform.MacOS
|
||||||
private bool WindowShouldClose(IntPtr self, IntPtr cmd, IntPtr sender)
|
private bool WindowShouldClose(IntPtr self, IntPtr cmd, IntPtr sender)
|
||||||
{
|
{
|
||||||
var cancelArgs = new CancelEventArgs();
|
var cancelArgs = new CancelEventArgs();
|
||||||
Closing(this, cancelArgs);
|
OnClosing(cancelArgs);
|
||||||
|
|
||||||
if (!cancelArgs.Cancel)
|
if (!cancelArgs.Cancel)
|
||||||
{
|
{
|
||||||
Closed(this, EventArgs.Empty);
|
OnClosed(EventArgs.Empty);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -377,7 +371,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
Cocoa.SendVoid(owner, selAddTrackingArea, trackingArea);
|
Cocoa.SendVoid(owner, selAddTrackingArea, trackingArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
shouldClose = true;
|
shouldClose = true;
|
||||||
}
|
}
|
||||||
|
@ -391,13 +385,6 @@ namespace OpenTK.Platform.MacOS
|
||||||
return modifiers;
|
return modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GetKey(ushort keyCode, NSEventModifierMask modifierFlags, OpenTK.Input.KeyboardKeyEventArgs args)
|
|
||||||
{
|
|
||||||
args.Key = MacOSKeyMap.GetKey((Carbon.MacOSKeyCode)keyCode);
|
|
||||||
args.Modifiers = GetModifiers(modifierFlags);
|
|
||||||
args.ScanCode = (uint)keyCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MouseButton GetMouseButton(int cocoaButtonIndex)
|
private MouseButton GetMouseButton(int cocoaButtonIndex)
|
||||||
{
|
{
|
||||||
if (cocoaButtonIndex == 0) return MouseButton.Left;
|
if (cocoaButtonIndex == 0) return MouseButton.Left;
|
||||||
|
@ -409,8 +396,10 @@ namespace OpenTK.Platform.MacOS
|
||||||
return (MouseButton)cocoaButtonIndex;
|
return (MouseButton)cocoaButtonIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessEvents()
|
public override void ProcessEvents()
|
||||||
{
|
{
|
||||||
|
base.ProcessEvents();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var e = Cocoa.SendIntPtr(NSApplication.Handle, selNextEventMatchingMask, uint.MaxValue, IntPtr.Zero, NSDefaultRunLoopMode, true);
|
var e = Cocoa.SendIntPtr(NSApplication.Handle, selNextEventMatchingMask, uint.MaxValue, IntPtr.Zero, NSDefaultRunLoopMode, true);
|
||||||
|
@ -423,16 +412,11 @@ namespace OpenTK.Platform.MacOS
|
||||||
{
|
{
|
||||||
case NSEventType.KeyDown:
|
case NSEventType.KeyDown:
|
||||||
{
|
{
|
||||||
var keyCode = Cocoa.SendUshort(e, selKeyCode);
|
MacOSKeyCode keyCode = (MacOSKeyCode)Cocoa.SendUshort(e, selKeyCode);
|
||||||
var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags);
|
|
||||||
var isARepeat = Cocoa.SendBool(e, selIsARepeat);
|
var isARepeat = Cocoa.SendBool(e, selIsARepeat);
|
||||||
GetKey(keyCode, modifierFlags, keyArgs);
|
Key key = MacOSKeyMap.GetKey(keyCode);
|
||||||
InputDriver.Keyboard[0].SetKey(keyArgs.Key, keyArgs.ScanCode, true);
|
|
||||||
|
|
||||||
if (!isARepeat || InputDriver.Keyboard[0].KeyRepeat)
|
OnKeyDown(key, isARepeat);
|
||||||
{
|
|
||||||
KeyDown(this, keyArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
var s = Cocoa.FromNSString(Cocoa.SendIntPtr(e, selCharactersIgnoringModifiers));
|
var s = Cocoa.FromNSString(Cocoa.SendIntPtr(e, selCharactersIgnoringModifiers));
|
||||||
foreach (var c in s)
|
foreach (var c in s)
|
||||||
|
@ -440,10 +424,9 @@ namespace OpenTK.Platform.MacOS
|
||||||
int intVal = (int)c;
|
int intVal = (int)c;
|
||||||
if (!Char.IsControl(c) && (intVal < 63232 || intVal > 63235))
|
if (!Char.IsControl(c) && (intVal < 63232 || intVal > 63235))
|
||||||
{
|
{
|
||||||
// For some reason, arrow keys (mapped 63232-63235) are seen as non-control characters, so get rid of those.
|
// For some reason, arrow keys (mapped 63232-63235)
|
||||||
|
// are seen as non-control characters, so get rid of those.
|
||||||
keyPressArgs.KeyChar = c;
|
OnKeyPress(c);
|
||||||
KeyPress(this, keyPressArgs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,13 +434,16 @@ namespace OpenTK.Platform.MacOS
|
||||||
|
|
||||||
case NSEventType.KeyUp:
|
case NSEventType.KeyUp:
|
||||||
{
|
{
|
||||||
var keyCode = Cocoa.SendUshort(e, selKeyCode);
|
MacOSKeyCode keyCode = (MacOSKeyCode)Cocoa.SendUshort(e, selKeyCode);
|
||||||
|
Key key = MacOSKeyMap.GetKey(keyCode);
|
||||||
|
OnKeyUp(key);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NSEventType.FlagsChanged:
|
||||||
|
{
|
||||||
var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags);
|
var modifierFlags = (NSEventModifierMask)Cocoa.SendUint(e, selModifierFlags);
|
||||||
|
UpdateModifierFlags(GetModifiers(modifierFlags));
|
||||||
GetKey(keyCode, modifierFlags, keyArgs);
|
|
||||||
InputDriver.Keyboard[0].SetKey(keyArgs.Key, keyArgs.ScanCode, false);
|
|
||||||
|
|
||||||
KeyUp(this, keyArgs);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -472,8 +458,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
//SetCursor(selectedCursor);
|
//SetCursor(selectedCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorInsideWindow = true;
|
OnMouseEnter(EventArgs.Empty);
|
||||||
MouseEnter(this, EventArgs.Empty);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -486,11 +471,10 @@ namespace OpenTK.Platform.MacOS
|
||||||
{
|
{
|
||||||
if (selectedCursor != MouseCursor.Default)
|
if (selectedCursor != MouseCursor.Default)
|
||||||
{
|
{
|
||||||
SetCursor(MouseCursor.Default);
|
//SetCursor(MouseCursor.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursorInsideWindow = false;
|
OnMouseLeave(EventArgs.Empty);
|
||||||
MouseLeave(this, EventArgs.Empty);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -500,6 +484,10 @@ namespace OpenTK.Platform.MacOS
|
||||||
case NSEventType.OtherMouseDragged:
|
case NSEventType.OtherMouseDragged:
|
||||||
case NSEventType.MouseMoved:
|
case NSEventType.MouseMoved:
|
||||||
{
|
{
|
||||||
|
Point p = new Point(MouseState.X, MouseState.Y);
|
||||||
|
if (CursorVisible)
|
||||||
|
{
|
||||||
|
// Use absolute coordinates
|
||||||
var pf = Cocoa.SendPoint(e, selLocationInWindowOwner);
|
var pf = Cocoa.SendPoint(e, selLocationInWindowOwner);
|
||||||
|
|
||||||
// Convert from points to pixel coordinates
|
// Convert from points to pixel coordinates
|
||||||
|
@ -507,11 +495,27 @@ namespace OpenTK.Platform.MacOS
|
||||||
new RectangleF(pf.X, pf.Y, 0, 0));
|
new RectangleF(pf.X, pf.Y, 0, 0));
|
||||||
|
|
||||||
// See CocoaDrawingGuide under "Converting from Window to View Coordinates"
|
// See CocoaDrawingGuide under "Converting from Window to View Coordinates"
|
||||||
var p = new Point(
|
p = new Point(
|
||||||
MathHelper.Clamp((int)Math.Round(rf.X), 0, Width),
|
MathHelper.Clamp((int)Math.Round(rf.X), 0, Width),
|
||||||
MathHelper.Clamp((int)Math.Round(Height - rf.Y), 0, Height));
|
MathHelper.Clamp((int)Math.Round(Height - rf.Y), 0, Height));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Mouse has been disassociated,
|
||||||
|
// use relative coordinates
|
||||||
|
var dx = Cocoa.SendFloat(e, selDeltaX);
|
||||||
|
var dy = Cocoa.SendFloat(e, selDeltaY);
|
||||||
|
|
||||||
InputDriver.Mouse[0].Position = p;
|
p = new Point(
|
||||||
|
MathHelper.Clamp((int)Math.Round(p.X + dx), 0, Width),
|
||||||
|
MathHelper.Clamp((int)Math.Round(p.Y + dy), 0, Height));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only raise events when the mouse has actually moved
|
||||||
|
if (MouseState.X != p.X || MouseState.Y != p.Y)
|
||||||
|
{
|
||||||
|
OnMouseMove(p.X, p.Y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -520,15 +524,23 @@ namespace OpenTK.Platform.MacOS
|
||||||
|
|
||||||
case NSEventType.ScrollWheel:
|
case NSEventType.ScrollWheel:
|
||||||
{
|
{
|
||||||
var scrollingDelta = Cocoa.SendFloat(e, selScrollingDeltaY);
|
float dx, dy;
|
||||||
var factor = 1.0f;
|
|
||||||
|
|
||||||
if (Cocoa.SendBool(e, selHasPreciseScrollingDeltas))
|
if (Cocoa.SendBool(e, selHasPreciseScrollingDeltas))
|
||||||
{
|
{
|
||||||
factor = 1.0f / scrollFactor; // Problem: Don't know what factor to use here, but this seems to work.
|
dx = Cocoa.SendFloat(e, selScrollingDeltaX) / scrollFactor;
|
||||||
|
dy = Cocoa.SendFloat(e, selScrollingDeltaY) / scrollFactor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dx = Cocoa.SendFloat(e, selDeltaX);
|
||||||
|
dy = Cocoa.SendFloat(e, selDeltaY);
|
||||||
}
|
}
|
||||||
|
|
||||||
InputDriver.Mouse[0].WheelPrecise += scrollingDelta * factor;
|
// Only raise wheel events when the user has actually scrolled
|
||||||
|
if (dx != 0 || dy != 0)
|
||||||
|
{
|
||||||
|
OnMouseWheel(dx, dy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -537,7 +549,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
case NSEventType.OtherMouseDown:
|
case NSEventType.OtherMouseDown:
|
||||||
{
|
{
|
||||||
var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
|
var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
|
||||||
InputDriver.Mouse[0][GetMouseButton(buttonNumber)] = true;
|
OnMouseDown(GetMouseButton(buttonNumber));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -546,7 +558,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
case NSEventType.OtherMouseUp:
|
case NSEventType.OtherMouseUp:
|
||||||
{
|
{
|
||||||
var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
|
var buttonNumber = Cocoa.SendInt(e, selButtonNumber);
|
||||||
InputDriver.Mouse[0][GetMouseButton(buttonNumber)] = false;
|
OnMouseUp(GetMouseButton(buttonNumber));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -575,19 +587,25 @@ namespace OpenTK.Platform.MacOS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Drawing.Point PointToClient(System.Drawing.Point point)
|
public override System.Drawing.Point PointToClient(System.Drawing.Point point)
|
||||||
{
|
{
|
||||||
var r = Cocoa.SendRect(windowInfo.Handle, selConvertRectFromScreen, new RectangleF(point.X, point.Y, 0, 0));
|
var r =
|
||||||
return new Point((int)r.X, (int)(GetContentViewFrame().Height - GetCurrentScreenFrame().Height - r.Y));
|
Cocoa.SendRect(windowInfo.ViewHandle, selConvertRectToBacking,
|
||||||
|
Cocoa.SendRect(windowInfo.Handle, selConvertRectFromScreen,
|
||||||
|
new RectangleF(point.X, GetCurrentScreenFrame().Height - point.Y, 0, 0)));
|
||||||
|
return new Point((int)r.X, (int)(Height - r.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Drawing.Point PointToScreen(System.Drawing.Point point)
|
public override System.Drawing.Point PointToScreen(System.Drawing.Point point)
|
||||||
{
|
{
|
||||||
var r = Cocoa.SendRect(windowInfo.Handle, selConvertRectToScreen, new RectangleF(point.X, point.Y, 0, 0));
|
var r =
|
||||||
return new Point((int)r.X, (int)(-GetContentViewFrame().Height + GetCurrentScreenFrame().Height - r.Y));
|
Cocoa.SendRect(windowInfo.Handle, selConvertRectToScreen,
|
||||||
|
Cocoa.SendRect(windowInfo.ViewHandle, selConvertRectFromBacking,
|
||||||
|
new RectangleF(point.X, Height - point.Y, 0, 0)));
|
||||||
|
return new Point((int)r.X, (int)(GetCurrentScreenFrame().Height - r.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Drawing.Icon Icon
|
public override System.Drawing.Icon Icon
|
||||||
{
|
{
|
||||||
get { return icon; }
|
get { return icon; }
|
||||||
set
|
set
|
||||||
|
@ -598,11 +616,11 @@ namespace OpenTK.Platform.MacOS
|
||||||
IntPtr nsimg = Cocoa.ToNSImage(img);
|
IntPtr nsimg = Cocoa.ToNSImage(img);
|
||||||
Cocoa.SendVoid(NSApplication.Handle, selSetApplicationIconImage, nsimg);
|
Cocoa.SendVoid(NSApplication.Handle, selSetApplicationIconImage, nsimg);
|
||||||
}
|
}
|
||||||
IconChanged(this, EventArgs.Empty);
|
OnIconChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Title
|
public override string Title
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -614,7 +632,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Focused
|
public override bool Focused
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -622,7 +640,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Visible
|
public override bool Visible
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -631,11 +649,11 @@ namespace OpenTK.Platform.MacOS
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Cocoa.SendVoid(windowInfo.Handle, selSetIsVisible, value);
|
Cocoa.SendVoid(windowInfo.Handle, selSetIsVisible, value);
|
||||||
VisibleChanged(this, EventArgs.Empty);
|
OnVisibleChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Exists
|
public override bool Exists
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -643,7 +661,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWindowInfo WindowInfo
|
public override IWindowInfo WindowInfo
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -702,7 +720,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
previousWindowBorder = null;
|
previousWindowBorder = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WindowState WindowState
|
public override WindowState WindowState
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -735,7 +753,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
InternalBounds = GetCurrentScreenFrame();
|
InternalBounds = GetCurrentScreenFrame();
|
||||||
|
|
||||||
windowState = value;
|
windowState = value;
|
||||||
WindowStateChanged(this, EventArgs.Empty);
|
OnWindowStateChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
else if (value == WindowState.Maximized)
|
else if (value == WindowState.Maximized)
|
||||||
{
|
{
|
||||||
|
@ -748,13 +766,13 @@ namespace OpenTK.Platform.MacOS
|
||||||
else if (value == WindowState.Normal)
|
else if (value == WindowState.Normal)
|
||||||
{
|
{
|
||||||
windowState = value;
|
windowState = value;
|
||||||
WindowStateChanged(this, EventArgs.Empty);
|
OnWindowStateChanged(EventArgs.Empty);
|
||||||
Resize(this, EventArgs.Empty);
|
OnResize(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public WindowBorder WindowBorder
|
public override WindowBorder WindowBorder
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -773,7 +791,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SetWindowBorder(value);
|
SetWindowBorder(value);
|
||||||
WindowBorderChanged(this, EventArgs.Empty);
|
OnWindowBorderChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -795,16 +813,26 @@ namespace OpenTK.Platform.MacOS
|
||||||
return (NSWindowStyle)0;
|
return (NSWindowStyle)0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Drawing.Rectangle Bounds
|
public override System.Drawing.Rectangle Bounds
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var r = Cocoa.SendRect(windowInfo.Handle, selFrame);
|
var r = Cocoa.SendRect(windowInfo.Handle, selFrame);
|
||||||
return new Rectangle((int)r.X, (int)(GetCurrentScreenFrame().Height - r.Y), (int)r.Width, (int)r.Height);
|
return new Rectangle(
|
||||||
|
(int)r.X,
|
||||||
|
(int)(GetCurrentScreenFrame().Height - r.Y - r.Height),
|
||||||
|
(int)r.Width,
|
||||||
|
(int)r.Height);
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Cocoa.SendVoid(windowInfo.Handle, selSetFrame, new RectangleF(value.X, GetCurrentScreenFrame().Height - value.Y, value.Width, value.Height), true);
|
Cocoa.SendVoid(windowInfo.Handle, selSetFrame,
|
||||||
|
new RectangleF(
|
||||||
|
value.X,
|
||||||
|
GetCurrentScreenFrame().Height - value.Y - value.Height,
|
||||||
|
value.Width,
|
||||||
|
value.Height),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,105 +848,13 @@ namespace OpenTK.Platform.MacOS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public System.Drawing.Point Location
|
public override System.Drawing.Size ClientSize
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Bounds.Location;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
var b = Bounds;
|
|
||||||
b.Location = value;
|
|
||||||
Bounds = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Drawing.Size Size
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Bounds.Size;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
var b = Bounds;
|
|
||||||
b.Y -= Bounds.Height;
|
|
||||||
b.Y += value.Height;
|
|
||||||
b.Size = value;
|
|
||||||
Bounds = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int X
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Bounds.X;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
var b = Bounds;
|
|
||||||
b.X = value;
|
|
||||||
Bounds = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Y
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Bounds.Y;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
var b = Bounds;
|
|
||||||
b.Y = value;
|
|
||||||
Bounds = b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Width
|
|
||||||
{
|
|
||||||
get { return ClientRectangle.Width; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
var s = ClientSize;
|
|
||||||
s.Width = value;
|
|
||||||
ClientSize = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Height
|
|
||||||
{
|
|
||||||
get { return ClientRectangle.Height; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
var s = ClientSize;
|
|
||||||
s.Height = value;
|
|
||||||
ClientSize = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Drawing.Rectangle ClientRectangle
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var contentViewBounds = Cocoa.SendRect(windowInfo.ViewHandle, selBounds);
|
var contentViewBounds = Cocoa.SendRect(windowInfo.ViewHandle, selBounds);
|
||||||
var bounds = Cocoa.SendRect(windowInfo.Handle, selConvertRectToBacking, contentViewBounds);
|
var bounds = Cocoa.SendRect(windowInfo.Handle, selConvertRectToBacking, contentViewBounds);
|
||||||
return new Rectangle((int)bounds.X, (int)bounds.Y, (int)bounds.Width, (int)bounds.Height);
|
return new Size((int)bounds.Width, (int)bounds.Height);
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ClientSize = value.Size; // Just set size, to be consistent with WinGLNative.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Drawing.Size ClientSize
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ClientRectangle.Size;
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
@ -928,15 +864,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenTK.Input.IInputDriver InputDriver
|
public override MouseCursor Cursor
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return inputDriver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MouseCursor Cursor
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1058,7 +986,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
Cocoa.SendVoid(windowInfo.Handle, selInvalidateCursorRectsForView, windowInfo.ViewHandle);
|
Cocoa.SendVoid(windowInfo.Handle, selInvalidateCursorRectsForView, windowInfo.ViewHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CursorVisible
|
public override bool CursorVisible
|
||||||
{
|
{
|
||||||
get { return cursorVisible; }
|
get { return cursorVisible; }
|
||||||
set
|
set
|
||||||
|
@ -1075,13 +1003,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
protected override void Dispose(bool disposing)
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
|
||||||
{
|
{
|
||||||
if (disposed)
|
if (disposed)
|
||||||
return;
|
return;
|
||||||
|
@ -1105,12 +1027,12 @@ namespace OpenTK.Platform.MacOS
|
||||||
Cocoa.SendVoid(windowInfo.Handle, Selector.Release);
|
Cocoa.SendVoid(windowInfo.Handle, Selector.Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
Disposed(this, EventArgs.Empty);
|
OnDisposed(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
~CocoaNativeWindow()
|
public static IntPtr GetView(IntPtr windowHandle)
|
||||||
{
|
{
|
||||||
Dispose(false);
|
return Cocoa.SendIntPtr(windowHandle, selContentView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RectangleF GetContentViewFrame()
|
private RectangleF GetContentViewFrame()
|
||||||
|
@ -1135,23 +1057,25 @@ namespace OpenTK.Platform.MacOS
|
||||||
|
|
||||||
private void SetCursorVisible(bool visible)
|
private void SetCursorVisible(bool visible)
|
||||||
{
|
{
|
||||||
Carbon.CG.AssociateMouseAndMouseCursorPosition(visible);
|
// If the mouse is outside the window and we want to hide it,
|
||||||
Cocoa.SendVoid(NSCursor, visible ? selUnhide : selHide);
|
// move it inside the window first.
|
||||||
|
// Otherwise, if we are making the cursor visible again,
|
||||||
|
// we place it in the same spot as reported in the current
|
||||||
|
// MouseState to avoid sudden jumps.
|
||||||
|
if (!visible && !Bounds.Contains(new Point(MouseState.X, MouseState.Y)))
|
||||||
|
{
|
||||||
|
Mouse.SetPosition(
|
||||||
|
(Bounds.Left + Bounds.Right) / 2,
|
||||||
|
(Bounds.Top + Bounds.Bottom) / 2);
|
||||||
|
}
|
||||||
|
else if (visible)
|
||||||
|
{
|
||||||
|
var p = PointToScreen(new Point(MouseState.X, MouseState.Y));
|
||||||
|
Mouse.SetPosition((int)p.X, (int)p.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetCursor(MouseCursor cursor)
|
Carbon.CG.AssociateMouseAndMouseCursorPosition(visible);
|
||||||
{
|
Cocoa.SendVoid(NSCursor, visible ? selUnhide : selHide);
|
||||||
if (cursor == MouseCursor.Default)
|
|
||||||
{
|
|
||||||
Cocoa.SendVoid(NSCursor, selUnhide);
|
|
||||||
}
|
|
||||||
else if (cursor == MouseCursor.Empty)
|
|
||||||
{
|
|
||||||
Cocoa.SendVoid(NSCursor, selHide);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetMenuVisible(bool visible)
|
private void SetMenuVisible(bool visible)
|
||||||
|
@ -1178,7 +1102,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
Cocoa.SendIntPtr(windowInfo.Handle, selSetTitle, Cocoa.ToNSString(title));
|
Cocoa.SendIntPtr(windowInfo.Handle, selSetTitle, Cocoa.ToNSString(title));
|
||||||
if (callEvent)
|
if (callEvent)
|
||||||
{
|
{
|
||||||
TitleChanged(this, EventArgs.Empty);
|
OnTitleChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,7 @@ namespace OpenTK.Platform.MacOS
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HIDUsageGD.Wheel:
|
case HIDUsageGD.Wheel:
|
||||||
mouse.State.WheelPrecise += v_int;
|
mouse.State.SetScrollRelative(0, v_int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -332,6 +332,15 @@ namespace OpenTK.Platform.MacOS
|
||||||
case HIDPage.Button:
|
case HIDPage.Button:
|
||||||
mouse.State[OpenTK.Input.MouseButton.Left + usage - 1] = v_int == 1;
|
mouse.State[OpenTK.Input.MouseButton.Left + usage - 1] = v_int == 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HIDPage.Consumer:
|
||||||
|
switch ((HIDUsageCD)usage)
|
||||||
|
{
|
||||||
|
case HIDUsageCD.ACPan:
|
||||||
|
mouse.State.SetScrollRelative(v_int, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +390,8 @@ namespace OpenTK.Platform.MacOS
|
||||||
{
|
{
|
||||||
Debug.Print("[Warning] Key {0} not mapped.", usage);
|
Debug.Print("[Warning] Key {0} not mapped.", usage);
|
||||||
}
|
}
|
||||||
keyboard.State.SetKeyState(RawKeyMap[usage], (byte)usage, v_int != 0);
|
|
||||||
|
keyboard.State[RawKeyMap[usage]] = v_int != 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1107,6 +1117,12 @@ namespace OpenTK.Platform.MacOS
|
||||||
VendorDefinedStart = 0xFF00
|
VendorDefinedStart = 0xFF00
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Consumer electronic devices
|
||||||
|
enum HIDUsageCD
|
||||||
|
{
|
||||||
|
ACPan = 0x0238
|
||||||
|
}
|
||||||
|
|
||||||
// Generic desktop usage
|
// Generic desktop usage
|
||||||
enum HIDUsageGD
|
enum HIDUsageGD
|
||||||
{
|
{
|
||||||
|
|
477
Source/OpenTK/Platform/NativeWindowBase.cs
Normal file
477
Source/OpenTK/Platform/NativeWindowBase.cs
Normal file
|
@ -0,0 +1,477 @@
|
||||||
|
#region License
|
||||||
|
//
|
||||||
|
// NativeWindowBase.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;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
|
namespace OpenTK.Platform
|
||||||
|
{
|
||||||
|
// Common base class for all INativeWindow implementations
|
||||||
|
abstract class NativeWindowBase : INativeWindow
|
||||||
|
{
|
||||||
|
readonly LegacyInputDriver LegacyInputDriver;
|
||||||
|
|
||||||
|
readonly MouseButtonEventArgs MouseDownArgs = new MouseButtonEventArgs();
|
||||||
|
readonly MouseButtonEventArgs MouseUpArgs = new MouseButtonEventArgs();
|
||||||
|
readonly MouseMoveEventArgs MouseMoveArgs = new MouseMoveEventArgs();
|
||||||
|
readonly MouseWheelEventArgs MouseWheelArgs = new MouseWheelEventArgs();
|
||||||
|
|
||||||
|
readonly KeyboardKeyEventArgs KeyDownArgs = new KeyboardKeyEventArgs();
|
||||||
|
readonly KeyboardKeyEventArgs KeyUpArgs = new KeyboardKeyEventArgs();
|
||||||
|
readonly KeyPressEventArgs KeyPressArgs = new KeyPressEventArgs((char)0);
|
||||||
|
|
||||||
|
// In order to simplify mouse event implementation,
|
||||||
|
// we can store the current mouse state here.
|
||||||
|
protected MouseState MouseState = new MouseState();
|
||||||
|
protected KeyboardState KeyboardState = new KeyboardState();
|
||||||
|
|
||||||
|
MouseState PreviousMouseState = new MouseState();
|
||||||
|
|
||||||
|
internal NativeWindowBase()
|
||||||
|
{
|
||||||
|
LegacyInputDriver = new LegacyInputDriver(this);
|
||||||
|
MouseState.SetIsConnected(true);
|
||||||
|
KeyboardState.SetIsConnected(true);
|
||||||
|
PreviousMouseState.SetIsConnected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Protected Members
|
||||||
|
|
||||||
|
protected void OnMove(EventArgs e)
|
||||||
|
{
|
||||||
|
Move(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnResize(EventArgs e)
|
||||||
|
{
|
||||||
|
Resize(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnClosing(CancelEventArgs e)
|
||||||
|
{
|
||||||
|
Closing(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnClosed(EventArgs e)
|
||||||
|
{
|
||||||
|
Closed(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnDisposed(EventArgs e)
|
||||||
|
{
|
||||||
|
Disposed(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnIconChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
IconChanged(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnTitleChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
TitleChanged(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnVisibleChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
VisibleChanged(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnFocusedChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
FocusedChanged(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnWindowBorderChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
WindowBorderChanged(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnWindowStateChanged(EventArgs e)
|
||||||
|
{
|
||||||
|
WindowStateChanged(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnKeyDown(Key key, bool repeat)
|
||||||
|
{
|
||||||
|
KeyboardState.SetKeyState(key, true);
|
||||||
|
|
||||||
|
var e = KeyDownArgs;
|
||||||
|
e.Keyboard = KeyboardState;
|
||||||
|
e.Key = key;
|
||||||
|
e.IsRepeat = repeat;
|
||||||
|
KeyDown(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnKeyPress(char c)
|
||||||
|
{
|
||||||
|
var e = KeyPressArgs;
|
||||||
|
e.KeyChar = c;
|
||||||
|
KeyPress(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnKeyUp(Key key)
|
||||||
|
{
|
||||||
|
KeyboardState.SetKeyState(key, false);
|
||||||
|
|
||||||
|
var e = KeyUpArgs;
|
||||||
|
e.Keyboard = KeyboardState;
|
||||||
|
e.Key = key;
|
||||||
|
e.IsRepeat = false;
|
||||||
|
KeyUp(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \internal
|
||||||
|
/// <summary>
|
||||||
|
/// Call this method to simulate KeyDown/KeyUp events
|
||||||
|
/// on platforms that do not generate key events for
|
||||||
|
/// modifier flags (e.g. Mac/Cocoa).
|
||||||
|
/// Note: this method does not distinguish between the
|
||||||
|
/// left and right variants of modifier keys.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="mods">Mods.</param>
|
||||||
|
protected void UpdateModifierFlags(KeyModifiers mods)
|
||||||
|
{
|
||||||
|
bool alt = (mods & KeyModifiers.Alt) != 0;
|
||||||
|
bool control = (mods & KeyModifiers.Control) != 0;
|
||||||
|
bool shift = (mods & KeyModifiers.Shift) != 0;
|
||||||
|
|
||||||
|
if (alt)
|
||||||
|
{
|
||||||
|
OnKeyDown(Key.AltLeft, KeyboardState[Key.AltLeft]);
|
||||||
|
OnKeyDown(Key.AltRight, KeyboardState[Key.AltLeft]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (KeyboardState[Key.AltLeft])
|
||||||
|
{
|
||||||
|
OnKeyUp(Key.AltLeft);
|
||||||
|
}
|
||||||
|
if (KeyboardState[Key.AltRight])
|
||||||
|
{
|
||||||
|
OnKeyUp(Key.AltRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (control)
|
||||||
|
{
|
||||||
|
OnKeyDown(Key.ControlLeft, KeyboardState[Key.AltLeft]);
|
||||||
|
OnKeyDown(Key.ControlRight, KeyboardState[Key.AltLeft]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (KeyboardState[Key.ControlLeft])
|
||||||
|
{
|
||||||
|
OnKeyUp(Key.ControlLeft);
|
||||||
|
}
|
||||||
|
if (KeyboardState[Key.ControlRight])
|
||||||
|
{
|
||||||
|
OnKeyUp(Key.ControlRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shift)
|
||||||
|
{
|
||||||
|
OnKeyDown(Key.ShiftLeft, KeyboardState[Key.AltLeft]);
|
||||||
|
OnKeyDown(Key.ShiftRight, KeyboardState[Key.AltLeft]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (KeyboardState[Key.ShiftLeft])
|
||||||
|
{
|
||||||
|
OnKeyUp(Key.ShiftLeft);
|
||||||
|
}
|
||||||
|
if (KeyboardState[Key.ShiftRight])
|
||||||
|
{
|
||||||
|
OnKeyUp(Key.ShiftRight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnMouseLeave(EventArgs e)
|
||||||
|
{
|
||||||
|
MouseLeave(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnMouseEnter(EventArgs e)
|
||||||
|
{
|
||||||
|
MouseEnter(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnMouseDown(MouseButton button)
|
||||||
|
{
|
||||||
|
MouseState[button] = true;
|
||||||
|
|
||||||
|
var e = MouseDownArgs;
|
||||||
|
e.Mouse = MouseState;
|
||||||
|
|
||||||
|
MouseDown(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnMouseUp(MouseButton button)
|
||||||
|
{
|
||||||
|
MouseState[button] = false;
|
||||||
|
|
||||||
|
var e = MouseUpArgs;
|
||||||
|
e.Mouse = MouseState;
|
||||||
|
|
||||||
|
MouseUp(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnMouseMove(int x, int y)
|
||||||
|
{
|
||||||
|
MouseState.X = x;
|
||||||
|
MouseState.Y = y;
|
||||||
|
|
||||||
|
var e = MouseMoveArgs;
|
||||||
|
e.Mouse = MouseState;
|
||||||
|
e.XDelta = MouseState.X - PreviousMouseState.X;
|
||||||
|
e.YDelta = MouseState.Y - PreviousMouseState.Y;
|
||||||
|
|
||||||
|
if (e.XDelta == 0 && e.YDelta == 0)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("OnMouseMove called without moving the mouse");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PreviousMouseState = MouseState;
|
||||||
|
MouseMove(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnMouseWheel(float dx, float dy)
|
||||||
|
{
|
||||||
|
MouseState.SetScrollRelative(dx, dy);
|
||||||
|
|
||||||
|
var e = MouseWheelArgs;
|
||||||
|
e.Mouse = MouseState;
|
||||||
|
e.DeltaPrecise = MouseState.Scroll.Y - PreviousMouseState.Scroll.Y;
|
||||||
|
|
||||||
|
if (dx == 0 && dy == 0)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("OnMouseWheel called without moving the mouse wheel.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PreviousMouseState = MouseState;
|
||||||
|
MouseWheel(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region INativeWindow Members
|
||||||
|
|
||||||
|
public event EventHandler<EventArgs> Move = delegate { };
|
||||||
|
public event EventHandler<EventArgs> Resize = delegate { };
|
||||||
|
public event EventHandler<System.ComponentModel.CancelEventArgs> Closing = delegate { };
|
||||||
|
public event EventHandler<EventArgs> Closed = delegate { };
|
||||||
|
public event EventHandler<EventArgs> Disposed = delegate { };
|
||||||
|
public event EventHandler<EventArgs> IconChanged = delegate { };
|
||||||
|
public event EventHandler<EventArgs> TitleChanged = delegate { };
|
||||||
|
public event EventHandler<EventArgs> VisibleChanged = delegate { };
|
||||||
|
public event EventHandler<EventArgs> FocusedChanged = delegate { };
|
||||||
|
public event EventHandler<EventArgs> WindowBorderChanged = delegate { };
|
||||||
|
public event EventHandler<EventArgs> WindowStateChanged = delegate { };
|
||||||
|
public event EventHandler<KeyboardKeyEventArgs> KeyDown = delegate { };
|
||||||
|
public event EventHandler<KeyPressEventArgs> KeyPress = delegate { };
|
||||||
|
public event EventHandler<KeyboardKeyEventArgs> KeyUp = delegate { };
|
||||||
|
public event EventHandler<EventArgs> MouseLeave = delegate { };
|
||||||
|
public event EventHandler<EventArgs> MouseEnter = delegate { };
|
||||||
|
public event EventHandler<MouseButtonEventArgs> MouseDown = delegate { };
|
||||||
|
public event EventHandler<MouseButtonEventArgs> MouseUp = delegate { };
|
||||||
|
public event EventHandler<MouseMoveEventArgs> MouseMove = delegate { };
|
||||||
|
public event EventHandler<MouseWheelEventArgs> MouseWheel = delegate { };
|
||||||
|
|
||||||
|
public abstract void Close();
|
||||||
|
|
||||||
|
public virtual void ProcessEvents()
|
||||||
|
{
|
||||||
|
if (!Focused)
|
||||||
|
{
|
||||||
|
// Clear keyboard state, otherwise KeyUp
|
||||||
|
// events may be missed resulting in stuck
|
||||||
|
// keys.
|
||||||
|
for (Key key = 0; key < Key.LastKey; key++)
|
||||||
|
{
|
||||||
|
if (KeyboardState[key])
|
||||||
|
{
|
||||||
|
OnKeyUp(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Point PointToClient(Point point);
|
||||||
|
|
||||||
|
public abstract Point PointToScreen(Point point);
|
||||||
|
|
||||||
|
public abstract Icon Icon { get; set; }
|
||||||
|
|
||||||
|
public abstract string Title { get; set; }
|
||||||
|
|
||||||
|
public abstract bool Focused { get; }
|
||||||
|
|
||||||
|
public abstract bool Visible { get; set; }
|
||||||
|
|
||||||
|
public abstract bool Exists { get; }
|
||||||
|
|
||||||
|
public abstract IWindowInfo WindowInfo { get; }
|
||||||
|
|
||||||
|
public abstract WindowState WindowState { get; set; }
|
||||||
|
|
||||||
|
public abstract WindowBorder WindowBorder { get; set; }
|
||||||
|
|
||||||
|
public abstract Rectangle Bounds { get; set; }
|
||||||
|
|
||||||
|
public virtual Point Location
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Bounds.Location;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Bounds = new Rectangle(value, Bounds.Size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Size Size
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Bounds.Size;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Bounds = new Rectangle(Bounds.Location, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int X
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Bounds.X;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Rectangle old = Bounds;
|
||||||
|
Bounds = new Rectangle(value, old.Y, old.Width, old.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Y
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Bounds.Y;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Rectangle old = Bounds;
|
||||||
|
Bounds = new Rectangle(old.X, value, old.Width, old.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Width
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ClientSize.Width;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Rectangle old = ClientRectangle;
|
||||||
|
ClientRectangle = new Rectangle(old.X, old.Y, value, old.Height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Height
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ClientSize.Height;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Rectangle old = ClientRectangle;
|
||||||
|
Bounds = new Rectangle(old.X, old.Y, old.Width, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Rectangle ClientRectangle
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new Rectangle(Point.Empty, ClientSize);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ClientSize = value.Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Size ClientSize { get; set; }
|
||||||
|
|
||||||
|
public virtual IInputDriver InputDriver
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return LegacyInputDriver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract bool CursorVisible { get; set; }
|
||||||
|
|
||||||
|
public abstract MouseCursor Cursor { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void Dispose(bool disposing);
|
||||||
|
|
||||||
|
~NativeWindowBase()
|
||||||
|
{
|
||||||
|
Debug.Print("NativeWindowBase leaked, did you forget to call Dispose()?");
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1572,8 +1572,8 @@ namespace OpenTK.Platform.SDL2
|
||||||
public UInt32 Which;
|
public UInt32 Which;
|
||||||
public Button Button;
|
public Button Button;
|
||||||
public State State;
|
public State State;
|
||||||
|
public byte Clicks;
|
||||||
byte padding1;
|
byte padding1;
|
||||||
byte padding2;
|
|
||||||
public Int32 X;
|
public Int32 X;
|
||||||
public Int32 Y;
|
public Int32 Y;
|
||||||
}
|
}
|
||||||
|
@ -1584,10 +1584,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
public uint Timestamp;
|
public uint Timestamp;
|
||||||
public uint WindowID;
|
public uint WindowID;
|
||||||
public uint Which;
|
public uint Which;
|
||||||
public State State;
|
public ButtonFlags State;
|
||||||
byte padding1;
|
|
||||||
byte padding2;
|
|
||||||
byte padding3;
|
|
||||||
public Int32 X;
|
public Int32 X;
|
||||||
public Int32 Y;
|
public Int32 Y;
|
||||||
public Int32 Xrel;
|
public Int32 Xrel;
|
||||||
|
@ -1617,10 +1614,6 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
|
|
||||||
public const uint TouchMouseID = 0xffffffff;
|
public const uint TouchMouseID = 0xffffffff;
|
||||||
|
|
||||||
public static class GL
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Rect
|
struct Rect
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
public override INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
public override INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
|
||||||
{
|
{
|
||||||
return new Sdl2NativeWindow(x, y, width, height, title, options, device, InputDriver);
|
return new Sdl2NativeWindow(x, y, width, height, title, options, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||||
|
|
|
@ -34,7 +34,7 @@ using OpenTK.Input;
|
||||||
|
|
||||||
namespace OpenTK.Platform.SDL2
|
namespace OpenTK.Platform.SDL2
|
||||||
{
|
{
|
||||||
class Sdl2InputDriver : IInputDriver2, IInputDriver
|
class Sdl2InputDriver : IInputDriver2
|
||||||
{
|
{
|
||||||
readonly static Dictionary<IntPtr, Sdl2InputDriver> DriverHandles =
|
readonly static Dictionary<IntPtr, Sdl2InputDriver> DriverHandles =
|
||||||
new Dictionary<IntPtr, Sdl2InputDriver>();
|
new Dictionary<IntPtr, Sdl2InputDriver>();
|
||||||
|
@ -154,51 +154,6 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IInputDriver Members
|
|
||||||
|
|
||||||
public void Poll()
|
|
||||||
{
|
|
||||||
joystick_driver.Poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IJoystickDriver Members
|
|
||||||
|
|
||||||
public IList<JoystickDevice> Joysticks
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return joystick_driver.Joysticks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IMouseDriver Members
|
|
||||||
|
|
||||||
public IList<MouseDevice> Mouse
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return mouse_driver.Mouse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IKeyboardDriver Members
|
|
||||||
|
|
||||||
public IList<KeyboardDevice> Keyboard
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return keyboard_driver.Keyboard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IInputDriver2 Members
|
#region IInputDriver2 Members
|
||||||
|
|
||||||
public IMouseDriver2 MouseDriver
|
public IMouseDriver2 MouseDriver
|
||||||
|
|
|
@ -298,6 +298,15 @@ namespace OpenTK.Platform.SDL2
|
||||||
return Key.Unknown;
|
return Key.Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static KeyModifiers GetModifiers(Keymod mod)
|
||||||
|
{
|
||||||
|
KeyModifiers result = 0;
|
||||||
|
result |= (mod & Keymod.ALT) != 0 ? KeyModifiers.Alt : 0;
|
||||||
|
result |= (mod & Keymod.CTRL) != 0 ? KeyModifiers.Control : 0;
|
||||||
|
result |= (mod & Keymod.SHIFT) != 0 ? KeyModifiers.Shift : 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ using OpenTK.Input;
|
||||||
|
|
||||||
namespace OpenTK.Platform.SDL2
|
namespace OpenTK.Platform.SDL2
|
||||||
{
|
{
|
||||||
class Sdl2Keyboard : IKeyboardDriver2, IKeyboardDriver
|
class Sdl2Keyboard : IKeyboardDriver2
|
||||||
{
|
{
|
||||||
KeyboardState state;
|
KeyboardState state;
|
||||||
|
|
||||||
|
@ -42,13 +42,6 @@ namespace OpenTK.Platform.SDL2
|
||||||
public Sdl2Keyboard()
|
public Sdl2Keyboard()
|
||||||
{
|
{
|
||||||
state.IsConnected = true;
|
state.IsConnected = true;
|
||||||
|
|
||||||
keyboards.Add(new KeyboardDevice());
|
|
||||||
keyboards[0].Description = "Standard keyboard";
|
|
||||||
keyboards[0].NumberOfFunctionKeys = 12;
|
|
||||||
keyboards[0].NumberOfKeys = 101;
|
|
||||||
keyboards[0].NumberOfLeds = 3;
|
|
||||||
keyboards_readonly = keyboards.AsReadOnly();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Private Members
|
#region Private Members
|
||||||
|
@ -65,16 +58,16 @@ namespace OpenTK.Platform.SDL2
|
||||||
{
|
{
|
||||||
Keymod mod = SDL.GetModState();
|
Keymod mod = SDL.GetModState();
|
||||||
|
|
||||||
state.SetKeyState(Key.LAlt, (byte)Scancode.LALT, (mod & Keymod.LALT) != 0);
|
state[Key.LAlt] = (mod & Keymod.LALT) != 0;
|
||||||
state.SetKeyState(Key.RAlt, (byte)Scancode.RALT, (mod & Keymod.RALT) != 0);
|
state[Key.RAlt] = (mod & Keymod.RALT) != 0;
|
||||||
state.SetKeyState(Key.LControl, (byte)Scancode.LCTRL, (mod & Keymod.LCTRL) != 0);
|
state[Key.LControl] = (mod & Keymod.LCTRL) != 0;
|
||||||
state.SetKeyState(Key.RControl, (byte)Scancode.RCTRL, (mod & Keymod.CTRL) != 0);
|
state[Key.RControl] = (mod & Keymod.RCTRL) != 0;
|
||||||
state.SetKeyState(Key.LShift, (byte)Scancode.LSHIFT, (mod & Keymod.LSHIFT) != 0);
|
state[Key.LShift] = (mod & Keymod.LSHIFT) != 0;
|
||||||
state.SetKeyState(Key.RShift, (byte)Scancode.RSHIFT, (mod & Keymod.RSHIFT) != 0);
|
state[Key.RShift] = (mod & Keymod.RSHIFT) != 0;
|
||||||
state.SetKeyState(Key.Menu, (byte)Scancode.APPLICATION, (mod & Keymod.GUI) != 0);
|
state[Key.Menu] = (mod & Keymod.GUI) != 0;
|
||||||
state.SetKeyState(Key.CapsLock, (byte)Scancode.CAPSLOCK, (mod & Keymod.CAPS) != 0);
|
state[Key.CapsLock] = (mod & Keymod.CAPS) != 0;
|
||||||
state.SetKeyState(Key.NumLock, (byte)Scancode.NUMLOCKCLEAR, (mod & Keymod.NUM) != 0);
|
state[Key.NumLock] = (mod & Keymod.NUM) != 0;
|
||||||
//state.SetKeyState(Key., (byte)Scancode.MODE, (mod & Keymod.MODE) != 0);
|
//state[Key.] = (mod & Keymod.MODE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -86,22 +79,11 @@ namespace OpenTK.Platform.SDL2
|
||||||
bool pressed = e.State != 0;
|
bool pressed = e.State != 0;
|
||||||
var scancode = e.Keysym.Scancode;
|
var scancode = e.Keysym.Scancode;
|
||||||
Key key = Sdl2KeyMap.GetKey(scancode);
|
Key key = Sdl2KeyMap.GetKey(scancode);
|
||||||
|
KeyModifiers mods = Sdl2KeyMap.GetModifiers(e.Keysym.Mod);
|
||||||
|
|
||||||
if (key != Key.Unknown)
|
if (key != Key.Unknown)
|
||||||
{
|
{
|
||||||
state.SetKeyState(key, (byte)scancode, pressed);
|
state[key] = pressed;
|
||||||
keyboards[0].SetKey(key, (byte)scancode, pressed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IKeyboardDriver Members
|
|
||||||
|
|
||||||
public IList<KeyboardDevice> Keyboard
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return keyboards_readonly;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,28 +33,18 @@ using OpenTK.Input;
|
||||||
|
|
||||||
namespace OpenTK.Platform.SDL2
|
namespace OpenTK.Platform.SDL2
|
||||||
{
|
{
|
||||||
class Sdl2Mouse : IMouseDriver2, IMouseDriver
|
class Sdl2Mouse : IMouseDriver2
|
||||||
{
|
{
|
||||||
MouseState state;
|
MouseState state;
|
||||||
|
|
||||||
readonly List<MouseDevice> mice =
|
|
||||||
new List<MouseDevice>();
|
|
||||||
readonly IList<MouseDevice> mice_readonly;
|
|
||||||
|
|
||||||
public Sdl2Mouse()
|
public Sdl2Mouse()
|
||||||
{
|
{
|
||||||
state.IsConnected = true;
|
state.IsConnected = true;
|
||||||
|
|
||||||
mice.Add(new MouseDevice());
|
|
||||||
mice[0].Description = "Standard mouse";
|
|
||||||
mice[0].NumberOfButtons = 3;
|
|
||||||
mice[0].NumberOfWheels = 1;
|
|
||||||
mice_readonly = mice.AsReadOnly();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Private Members
|
#region Private Members
|
||||||
|
|
||||||
MouseButton TranslateButton(Button button)
|
static internal MouseButton TranslateButton(Button button)
|
||||||
{
|
{
|
||||||
switch (button)
|
switch (button)
|
||||||
{
|
{
|
||||||
|
@ -97,34 +87,19 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
public void ProcessWheelEvent(MouseWheelEvent wheel)
|
public void ProcessWheelEvent(MouseWheelEvent wheel)
|
||||||
{
|
{
|
||||||
state.WheelPrecise += wheel.Y;
|
state.SetScrollRelative(0, wheel.Y);
|
||||||
mice[0].WheelPrecise += wheel.Y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessMouseEvent(MouseMotionEvent motion)
|
public void ProcessMouseEvent(MouseMotionEvent motion)
|
||||||
{
|
{
|
||||||
state.X += motion.Xrel;
|
state.X += motion.Xrel;
|
||||||
state.Y += motion.Yrel;
|
state.Y += motion.Yrel;
|
||||||
mice[0].Position = new Point(motion.X, motion.Y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessMouseEvent(MouseButtonEvent button)
|
public void ProcessMouseEvent(MouseButtonEvent button)
|
||||||
{
|
{
|
||||||
bool pressed = button.State == State.Pressed;
|
bool pressed = button.State == State.Pressed;
|
||||||
SetButtonState(TranslateButton(button.Button), pressed);
|
SetButtonState(TranslateButton(button.Button), pressed);
|
||||||
mice[0][TranslateButton(button.Button)] = pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IMouseDriver Members
|
|
||||||
|
|
||||||
public IList<MouseDevice> Mouse
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return mice_readonly;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -41,7 +41,7 @@ using System.Text;
|
||||||
|
|
||||||
namespace OpenTK.Platform.SDL2
|
namespace OpenTK.Platform.SDL2
|
||||||
{
|
{
|
||||||
class Sdl2NativeWindow : INativeWindow, IInputDriver
|
class Sdl2NativeWindow : NativeWindowBase
|
||||||
{
|
{
|
||||||
readonly object sync = new object();
|
readonly object sync = new object();
|
||||||
|
|
||||||
|
@ -66,25 +66,14 @@ namespace OpenTK.Platform.SDL2
|
||||||
// to .Net UTF16 strings
|
// to .Net UTF16 strings
|
||||||
char[] DecodeTextBuffer = new char[32];
|
char[] DecodeTextBuffer = new char[32];
|
||||||
|
|
||||||
// Argument for KeyPress event (allocated once to avoid runtime allocations)
|
|
||||||
readonly KeyPressEventArgs keypress_args = new KeyPressEventArgs('\0');
|
|
||||||
|
|
||||||
// Argument for KeyDown and KeyUp events (allocated once to avoid runtime allocations)
|
|
||||||
readonly KeyboardKeyEventArgs key_args = new KeyboardKeyEventArgs();
|
|
||||||
|
|
||||||
readonly IInputDriver input_driver;
|
|
||||||
|
|
||||||
static readonly Dictionary<uint, Sdl2NativeWindow> windows =
|
static readonly Dictionary<uint, Sdl2NativeWindow> windows =
|
||||||
new Dictionary<uint, Sdl2NativeWindow>();
|
new Dictionary<uint, Sdl2NativeWindow>();
|
||||||
|
|
||||||
public Sdl2NativeWindow(int x, int y, int width, int height,
|
public Sdl2NativeWindow(int x, int y, int width, int height,
|
||||||
string title, GameWindowFlags options, DisplayDevice device,
|
string title, GameWindowFlags options, DisplayDevice device)
|
||||||
IInputDriver input_driver)
|
|
||||||
{
|
{
|
||||||
lock (sync)
|
lock (sync)
|
||||||
{
|
{
|
||||||
this.input_driver = input_driver;
|
|
||||||
|
|
||||||
var bounds = device.Bounds;
|
var bounds = device.Bounds;
|
||||||
var flags = TranslateFlags(options);
|
var flags = TranslateFlags(options);
|
||||||
flags |= WindowFlags.OPENGL;
|
flags |= WindowFlags.OPENGL;
|
||||||
|
@ -180,7 +169,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
case EventType.MOUSEBUTTONUP:
|
case EventType.MOUSEBUTTONUP:
|
||||||
if (windows.TryGetValue(ev.Button.WindowID, out window))
|
if (windows.TryGetValue(ev.Button.WindowID, out window))
|
||||||
{
|
{
|
||||||
ProcessButtonEvent(window, ev);
|
ProcessMouseButtonEvent(window, ev.Button);
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -188,7 +177,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
case EventType.MOUSEMOTION:
|
case EventType.MOUSEMOTION:
|
||||||
if (windows.TryGetValue(ev.Motion.WindowID, out window))
|
if (windows.TryGetValue(ev.Motion.WindowID, out window))
|
||||||
{
|
{
|
||||||
ProcessMotionEvent(window, ev);
|
ProcessMouseMotionEvent(window, ev.Motion);
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -196,7 +185,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
case EventType.MOUSEWHEEL:
|
case EventType.MOUSEWHEEL:
|
||||||
if (windows.TryGetValue(ev.Wheel.WindowID, out window))
|
if (windows.TryGetValue(ev.Wheel.WindowID, out window))
|
||||||
{
|
{
|
||||||
ProcessWheelEvent(window, ev);
|
ProcessMouseWheelEvent(window, ev.Wheel);
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -214,9 +203,9 @@ namespace OpenTK.Platform.SDL2
|
||||||
return processed ? 0 : 1;
|
return processed ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessButtonEvent(Sdl2NativeWindow window, Event ev)
|
static void ProcessMouseButtonEvent(Sdl2NativeWindow window, MouseButtonEvent ev)
|
||||||
{
|
{
|
||||||
bool button_pressed = ev.Button.State == State.Pressed;
|
bool button_pressed = ev.State == State.Pressed;
|
||||||
|
|
||||||
// We need MouseUp events to be reported even if they occur
|
// We need MouseUp events to be reported even if they occur
|
||||||
// outside the window. SetWindowGrab ensures we get them.
|
// outside the window. SetWindowGrab ensures we get them.
|
||||||
|
@ -225,24 +214,30 @@ namespace OpenTK.Platform.SDL2
|
||||||
SDL.SetWindowGrab(window.window.Handle,
|
SDL.SetWindowGrab(window.window.Handle,
|
||||||
button_pressed ? true : false);
|
button_pressed ? true : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseButton button = Sdl2Mouse.TranslateButton(ev.Button);
|
||||||
|
if (button_pressed)
|
||||||
|
{
|
||||||
|
window.OnMouseDown(button);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window.OnMouseUp(button);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessKeyEvent(Sdl2NativeWindow window, Event ev)
|
static void ProcessKeyEvent(Sdl2NativeWindow window, Event ev)
|
||||||
{
|
{
|
||||||
bool key_pressed = ev.Key.State == State.Pressed;
|
bool key_pressed = ev.Key.State == State.Pressed;
|
||||||
var key = ev.Key.Keysym;
|
Key key = TranslateKey(ev.Key.Keysym.Scancode);
|
||||||
window.key_args.Key = TranslateKey(key.Scancode);
|
|
||||||
window.key_args.ScanCode = (uint)key.Scancode;
|
|
||||||
window.key_args.Modifiers = window.input_driver.Keyboard[0].GetModifiers();
|
|
||||||
if (key_pressed)
|
if (key_pressed)
|
||||||
{
|
{
|
||||||
window.KeyDown(window, window.key_args);
|
window.OnKeyDown(key, ev.Key.Repeat > 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
window.KeyUp(window, window.key_args);
|
window.OnKeyUp(key);
|
||||||
}
|
}
|
||||||
//window.keyboard.SetKey(TranslateKey(key.scancode), (uint)key.scancode, key_pressed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsafe void ProcessTextInputEvent(Sdl2NativeWindow window, TextInputEvent ev)
|
static unsafe void ProcessTextInputEvent(Sdl2NativeWindow window, TextInputEvent ev)
|
||||||
|
@ -273,21 +268,21 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
for (int i = 0; i < decoded_length; i++)
|
for (int i = 0; i < decoded_length; i++)
|
||||||
{
|
{
|
||||||
window.keypress_args.KeyChar = window.DecodeTextBuffer[i];
|
window.OnKeyPress(window.DecodeTextBuffer[i]);
|
||||||
window.KeyPress(window, window.keypress_args);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessMotionEvent(Sdl2NativeWindow window, Event ev)
|
static void ProcessMouseMotionEvent(Sdl2NativeWindow window, MouseMotionEvent ev)
|
||||||
{
|
{
|
||||||
float scale = window.ClientSize.Width / (float)window.Size.Width;
|
float scale = window.ClientSize.Width / (float)window.Size.Width;
|
||||||
//window.mouse.Position = new Point(
|
window.OnMouseMove(
|
||||||
// (int)(ev.motion.x * scale), (int)(ev.motion.y * scale));
|
(int)Math.Round(ev.X * scale),
|
||||||
|
(int)Math.Round(ev.Y * scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessWheelEvent(Sdl2NativeWindow window, Event ev)
|
static void ProcessMouseWheelEvent(Sdl2NativeWindow window, MouseWheelEvent ev)
|
||||||
{
|
{
|
||||||
//window.mouse.Wheel += ev.wheel.y;
|
window.OnMouseWheel(ev.X, ev.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessWindowEvent(Sdl2NativeWindow window, WindowEvent e)
|
static void ProcessWindowEvent(Sdl2NativeWindow window, WindowEvent e)
|
||||||
|
@ -299,7 +294,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
window.is_in_closing_event = true;
|
window.is_in_closing_event = true;
|
||||||
window.Closing(window, close_args);
|
window.OnClosing(close_args);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -308,17 +303,17 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
if (!close_args.Cancel)
|
if (!close_args.Cancel)
|
||||||
{
|
{
|
||||||
window.Closed(window, EventArgs.Empty);
|
window.OnClosed(EventArgs.Empty);
|
||||||
window.must_destroy = true;
|
window.must_destroy = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.ENTER:
|
case WindowEventID.ENTER:
|
||||||
window.MouseEnter(window, EventArgs.Empty);
|
window.OnMouseEnter(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.LEAVE:
|
case WindowEventID.LEAVE:
|
||||||
window.MouseLeave(window, EventArgs.Empty);
|
window.OnMouseLeave(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.EXPOSED:
|
case WindowEventID.EXPOSED:
|
||||||
|
@ -327,47 +322,47 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
case WindowEventID.FOCUS_GAINED:
|
case WindowEventID.FOCUS_GAINED:
|
||||||
window.is_focused = true;
|
window.is_focused = true;
|
||||||
window.FocusedChanged(window, EventArgs.Empty);
|
window.OnFocusedChanged(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.FOCUS_LOST:
|
case WindowEventID.FOCUS_LOST:
|
||||||
window.is_focused = false;
|
window.is_focused = false;
|
||||||
window.FocusedChanged(window, EventArgs.Empty);
|
window.OnFocusedChanged(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.HIDDEN:
|
case WindowEventID.HIDDEN:
|
||||||
window.is_visible = false;
|
window.is_visible = false;
|
||||||
window.VisibleChanged(window, EventArgs.Empty);
|
window.OnVisibleChanged(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.SHOWN:
|
case WindowEventID.SHOWN:
|
||||||
window.is_visible = true;
|
window.is_visible = true;
|
||||||
window.VisibleChanged(window, EventArgs.Empty);
|
window.OnVisibleChanged(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.MAXIMIZED:
|
case WindowEventID.MAXIMIZED:
|
||||||
window.window_state = WindowState.Maximized;
|
window.window_state = WindowState.Maximized;
|
||||||
window.WindowStateChanged(window, EventArgs.Empty);
|
window.OnWindowStateChanged(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.MINIMIZED:
|
case WindowEventID.MINIMIZED:
|
||||||
window.previous_window_state = window.window_state;
|
window.previous_window_state = window.window_state;
|
||||||
window.window_state = WindowState.Minimized;
|
window.window_state = WindowState.Minimized;
|
||||||
window.WindowStateChanged(window, EventArgs.Empty);
|
window.OnWindowStateChanged(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.RESTORED:
|
case WindowEventID.RESTORED:
|
||||||
window.window_state = window.previous_window_state;
|
window.window_state = window.previous_window_state;
|
||||||
window.WindowStateChanged(window, EventArgs.Empty);
|
window.OnWindowStateChanged(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.MOVED:
|
case WindowEventID.MOVED:
|
||||||
window.Move(window, EventArgs.Empty);
|
window.OnMove(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowEventID.RESIZED:
|
case WindowEventID.RESIZED:
|
||||||
case WindowEventID.SIZE_CHANGED:
|
case WindowEventID.SIZE_CHANGED:
|
||||||
window.Resize(window, EventArgs.Empty);
|
window.OnResize(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -402,6 +397,16 @@ namespace OpenTK.Platform.SDL2
|
||||||
SDL.ShowCursor(!grab);
|
SDL.ShowCursor(!grab);
|
||||||
SDL.SetWindowGrab(window.Handle, grab);
|
SDL.SetWindowGrab(window.Handle, grab);
|
||||||
SDL.SetRelativeMouseMode(grab);
|
SDL.SetRelativeMouseMode(grab);
|
||||||
|
if (!grab)
|
||||||
|
{
|
||||||
|
// Move the cursor to the current position
|
||||||
|
// in order to avoid a sudden jump when it
|
||||||
|
// becomes visible again
|
||||||
|
float scale = Width / (float)Size.Width;
|
||||||
|
SDL.WarpMouseInWindow(window.Handle,
|
||||||
|
(int)Math.Round(MouseState.X / scale),
|
||||||
|
(int)Math.Round(MouseState.Y / scale));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hack to force WindowState events to be pumped
|
// Hack to force WindowState events to be pumped
|
||||||
|
@ -443,24 +448,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
#region INativeWindow Members
|
#region INativeWindow Members
|
||||||
|
|
||||||
public event EventHandler<EventArgs> Move = delegate { };
|
public override MouseCursor Cursor
|
||||||
public event EventHandler<EventArgs> Resize = delegate { };
|
|
||||||
public event EventHandler<System.ComponentModel.CancelEventArgs> Closing = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Closed = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Disposed = delegate { };
|
|
||||||
public event EventHandler<EventArgs> IconChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> TitleChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> VisibleChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> FocusedChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> WindowBorderChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> WindowStateChanged = delegate { };
|
|
||||||
public event EventHandler<KeyboardKeyEventArgs> KeyDown = delegate { };
|
|
||||||
public event EventHandler<KeyPressEventArgs> KeyPress = delegate { };
|
|
||||||
public event EventHandler<KeyboardKeyEventArgs> KeyUp = delegate { };
|
|
||||||
public event EventHandler<EventArgs> MouseEnter = delegate { };
|
|
||||||
public event EventHandler<EventArgs> MouseLeave = delegate { };
|
|
||||||
|
|
||||||
public MouseCursor Cursor
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -540,7 +528,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
lock (sync)
|
lock (sync)
|
||||||
{
|
{
|
||||||
|
@ -560,8 +548,9 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ProcessEvents()
|
public override void ProcessEvents()
|
||||||
{
|
{
|
||||||
|
base.ProcessEvents();
|
||||||
lock (sync)
|
lock (sync)
|
||||||
{
|
{
|
||||||
if (Exists)
|
if (Exists)
|
||||||
|
@ -581,21 +570,21 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point PointToClient(Point point)
|
public override Point PointToClient(Point point)
|
||||||
{
|
{
|
||||||
var origin = DisplayDevice.Default.Bounds.Location;
|
var origin = DisplayDevice.Default.Bounds.Location;
|
||||||
var client = Location;
|
var client = Location;
|
||||||
return new Point(point.X + client.X - origin.X, point.Y + client.Y - origin.Y);
|
return new Point(point.X + client.X - origin.X, point.Y + client.Y - origin.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point PointToScreen(Point point)
|
public override Point PointToScreen(Point point)
|
||||||
{
|
{
|
||||||
var origin = DisplayDevice.Default.Bounds.Location;
|
var origin = DisplayDevice.Default.Bounds.Location;
|
||||||
var client = Location;
|
var client = Location;
|
||||||
return new Point(point.X + origin.X - client.X, point.Y + origin.Y - client.Y);
|
return new Point(point.X + origin.X - client.X, point.Y + origin.Y - client.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Icon Icon
|
public override Icon Icon
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -639,13 +628,13 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
|
|
||||||
icon = value;
|
icon = value;
|
||||||
IconChanged(this, EventArgs.Empty);
|
OnIconChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Title
|
public override string Title
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -671,7 +660,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Focused
|
public override bool Focused
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -679,7 +668,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Visible
|
public override bool Visible
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -700,7 +689,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Exists
|
public override bool Exists
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -708,7 +697,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IWindowInfo WindowInfo
|
public override IWindowInfo WindowInfo
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -716,7 +705,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public WindowState WindowState
|
public override WindowState WindowState
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -774,7 +763,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public WindowBorder WindowBorder
|
public override WindowBorder WindowBorder
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -810,13 +799,13 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
if (Exists)
|
if (Exists)
|
||||||
{
|
{
|
||||||
WindowBorderChanged(this, EventArgs.Empty);
|
OnWindowBorderChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rectangle Bounds
|
public override Rectangle Bounds
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -829,7 +818,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point Location
|
public override Point Location
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -856,7 +845,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Size Size
|
public override Size Size
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -883,67 +872,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int X
|
public override Size ClientSize
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Location.X;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Location = new Point(value, Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Y
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Location.Y;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Location = new Point(X, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Width
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ClientSize.Width;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ClientSize = new Size(value, Height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Height
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ClientSize.Height;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ClientSize = new Size(Width, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Rectangle ClientRectangle
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new Rectangle(new Point(), ClientSize);
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ClientSize = value.Size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Size ClientSize
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -967,15 +896,7 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IInputDriver InputDriver
|
public override bool CursorVisible
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return input_driver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool CursorVisible
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -996,54 +917,9 @@ namespace OpenTK.Platform.SDL2
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IInputDriver Members
|
|
||||||
|
|
||||||
public void Poll()
|
|
||||||
{
|
|
||||||
InputDriver.Poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IJoystickDriver Members
|
|
||||||
|
|
||||||
public IList<JoystickDevice> Joysticks
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return InputDriver.Joysticks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IMouseDriver Members
|
|
||||||
|
|
||||||
public IList<MouseDevice> Mouse
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return InputDriver.Mouse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IKeyboardDriver Members
|
|
||||||
|
|
||||||
public IList<KeyboardDevice> Keyboard
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return InputDriver.Keyboard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IDisposable implementation
|
#region IDisposable implementation
|
||||||
|
|
||||||
void Dispose(bool manual)
|
protected override void Dispose(bool manual)
|
||||||
{
|
{
|
||||||
if (!disposed)
|
if (!disposed)
|
||||||
{
|
{
|
||||||
|
@ -1082,17 +958,6 @@ namespace OpenTK.Platform.SDL2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Sdl2NativeWindow()
|
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3591,7 +3591,8 @@ namespace OpenTK.Platform.Windows
|
||||||
BUTTON_5_DOWN = 0x0100,
|
BUTTON_5_DOWN = 0x0100,
|
||||||
BUTTON_5_UP = 0x0200,
|
BUTTON_5_UP = 0x0200,
|
||||||
|
|
||||||
WHEEL = 0x0400
|
WHEEL = 0x0400,
|
||||||
|
HWHEEL = 0x0800,
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -4197,7 +4198,6 @@ namespace OpenTK.Platform.Windows
|
||||||
MBUTTONUP = 0x0208,
|
MBUTTONUP = 0x0208,
|
||||||
MBUTTONDBLCLK = 0x0209,
|
MBUTTONDBLCLK = 0x0209,
|
||||||
MOUSEWHEEL = 0x020A,
|
MOUSEWHEEL = 0x020A,
|
||||||
MOUSELAST = 0x020D,
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Windows 2000 and higher only.
|
/// Windows 2000 and higher only.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -4210,6 +4210,10 @@ namespace OpenTK.Platform.Windows
|
||||||
/// Windows 2000 and higher only.
|
/// Windows 2000 and higher only.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
XBUTTONDBLCLK = 0x020D,
|
XBUTTONDBLCLK = 0x020D,
|
||||||
|
/// <summary>
|
||||||
|
/// Windows Vista and higher only.
|
||||||
|
/// </summary>
|
||||||
|
MOUSEHWHEEL = 0x020E,
|
||||||
PARENTNOTIFY = 0x0210,
|
PARENTNOTIFY = 0x0210,
|
||||||
ENTERMENULOOP = 0x0211,
|
ENTERMENULOOP = 0x0211,
|
||||||
EXITMENULOOP = 0x0212,
|
EXITMENULOOP = 0x0212,
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace OpenTK.Platform.Windows
|
||||||
/// Drives GameWindow on Windows.
|
/// Drives GameWindow on Windows.
|
||||||
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
|
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal sealed class WinGLNative : INativeWindow, IInputDriver
|
internal sealed class WinGLNative : NativeWindowBase
|
||||||
{
|
{
|
||||||
#region Fields
|
#region Fields
|
||||||
|
|
||||||
|
@ -82,12 +82,6 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
const ClassStyle DefaultClassStyle = ClassStyle.OwnDC;
|
const ClassStyle DefaultClassStyle = ClassStyle.OwnDC;
|
||||||
|
|
||||||
// Used for IInputDriver implementation
|
|
||||||
IJoystickDriver joystick_driver = Factory.Default.CreateLegacyJoystickDriver();
|
|
||||||
KeyboardDevice keyboard = new KeyboardDevice();
|
|
||||||
MouseDevice mouse = new MouseDevice();
|
|
||||||
IList<KeyboardDevice> keyboards = new List<KeyboardDevice>(1);
|
|
||||||
IList<MouseDevice> mice = new List<MouseDevice>(1);
|
|
||||||
const long ExtendedBit = 1 << 24; // Used to distinguish left and right control, alt and enter keys.
|
const long ExtendedBit = 1 << 24; // Used to distinguish left and right control, alt and enter keys.
|
||||||
|
|
||||||
public static readonly uint ShiftLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LSHIFT, 0);
|
public static readonly uint ShiftLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LSHIFT, 0);
|
||||||
|
@ -97,10 +91,6 @@ namespace OpenTK.Platform.Windows
|
||||||
public static readonly uint AltLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LMENU, 0);
|
public static readonly uint AltLeftScanCode = Functions.MapVirtualKey(VirtualKeys.LMENU, 0);
|
||||||
public static readonly uint AltRightScanCode = Functions.MapVirtualKey(VirtualKeys.RMENU, 0);
|
public static readonly uint AltRightScanCode = Functions.MapVirtualKey(VirtualKeys.RMENU, 0);
|
||||||
|
|
||||||
KeyboardKeyEventArgs key_down = new KeyboardKeyEventArgs();
|
|
||||||
KeyboardKeyEventArgs key_up = new KeyboardKeyEventArgs();
|
|
||||||
KeyPressEventArgs key_press = new KeyPressEventArgs((char)0);
|
|
||||||
|
|
||||||
MouseCursor cursor = MouseCursor.Default;
|
MouseCursor cursor = MouseCursor.Default;
|
||||||
IntPtr cursor_handle = Functions.LoadCursor(CursorName.Arrow);
|
IntPtr cursor_handle = Functions.LoadCursor(CursorName.Arrow);
|
||||||
int cursor_visible_count = 0;
|
int cursor_visible_count = 0;
|
||||||
|
@ -160,18 +150,6 @@ namespace OpenTK.Platform.Windows
|
||||||
window);
|
window);
|
||||||
|
|
||||||
exists = true;
|
exists = true;
|
||||||
|
|
||||||
keyboard.Description = "Standard Windows keyboard";
|
|
||||||
keyboard.NumberOfFunctionKeys = 12;
|
|
||||||
keyboard.NumberOfKeys = 101;
|
|
||||||
keyboard.NumberOfLeds = 3;
|
|
||||||
|
|
||||||
mouse.Description = "Standard Windows mouse";
|
|
||||||
mouse.NumberOfButtons = 3;
|
|
||||||
mouse.NumberOfWheels = 1;
|
|
||||||
|
|
||||||
keyboards.Add(keyboard);
|
|
||||||
mice.Add(mouse);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +232,7 @@ namespace OpenTK.Platform.Windows
|
||||||
focused = (wParam.ToInt64() & 0xFFFF) != 0;
|
focused = (wParam.ToInt64() & 0xFFFF) != 0;
|
||||||
|
|
||||||
if (new_focused_state != Focused)
|
if (new_focused_state != Focused)
|
||||||
FocusedChanged(this, EventArgs.Empty);
|
OnFocusedChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleEnterModalLoop(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleEnterModalLoop(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
|
@ -292,7 +270,7 @@ namespace OpenTK.Platform.Windows
|
||||||
if (Location != new_location)
|
if (Location != new_location)
|
||||||
{
|
{
|
||||||
bounds.Location = new_location;
|
bounds.Location = new_location;
|
||||||
Move(this, EventArgs.Empty);
|
OnMove(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
Size new_size = new Size(pos->cx, pos->cy);
|
Size new_size = new Size(pos->cx, pos->cy);
|
||||||
|
@ -310,7 +288,7 @@ namespace OpenTK.Platform.Windows
|
||||||
SetWindowPosFlags.NOACTIVATE | SetWindowPosFlags.NOSENDCHANGING);
|
SetWindowPosFlags.NOACTIVATE | SetWindowPosFlags.NOSENDCHANGING);
|
||||||
|
|
||||||
if (suppress_resize <= 0)
|
if (suppress_resize <= 0)
|
||||||
Resize(this, EventArgs.Empty);
|
OnResize(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_in_modal_loop)
|
if (!is_in_modal_loop)
|
||||||
|
@ -352,7 +330,7 @@ namespace OpenTK.Platform.Windows
|
||||||
GrabCursor();
|
GrabCursor();
|
||||||
|
|
||||||
windowBorder = new_border;
|
windowBorder = new_border;
|
||||||
WindowBorderChanged(this, EventArgs.Empty);
|
OnWindowBorderChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,7 +358,7 @@ namespace OpenTK.Platform.Windows
|
||||||
if (new_state != windowState)
|
if (new_state != windowState)
|
||||||
{
|
{
|
||||||
windowState = new_state;
|
windowState = new_state;
|
||||||
WindowStateChanged(this, EventArgs.Empty);
|
OnWindowStateChanged(EventArgs.Empty);
|
||||||
|
|
||||||
// Ensure cursor remains grabbed
|
// Ensure cursor remains grabbed
|
||||||
if (!CursorVisible)
|
if (!CursorVisible)
|
||||||
|
@ -415,8 +393,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
if (!Char.IsControl(c))
|
if (!Char.IsControl(c))
|
||||||
{
|
{
|
||||||
key_press.KeyChar = c;
|
OnKeyPress(c);
|
||||||
KeyPress(this, key_press);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,8 +419,7 @@ namespace OpenTK.Platform.Windows
|
||||||
};
|
};
|
||||||
|
|
||||||
// Max points GetMouseMovePointsEx can return is 64.
|
// Max points GetMouseMovePointsEx can return is 64.
|
||||||
int numPoints = 64;
|
const int numPoints = 64;
|
||||||
|
|
||||||
MouseMovePoint* movePoints = stackalloc MouseMovePoint[numPoints];
|
MouseMovePoint* movePoints = stackalloc MouseMovePoint[numPoints];
|
||||||
|
|
||||||
// GetMouseMovePointsEx fills in movePoints so that the most
|
// GetMouseMovePointsEx fills in movePoints so that the most
|
||||||
|
@ -459,7 +435,7 @@ namespace OpenTK.Platform.Windows
|
||||||
if (points == 0 || (points == -1 && lastError == Constants.ERROR_POINT_NOT_FOUND))
|
if (points == 0 || (points == -1 && lastError == Constants.ERROR_POINT_NOT_FOUND))
|
||||||
{
|
{
|
||||||
// Just use the mouse move position
|
// Just use the mouse move position
|
||||||
mouse.Position = point;
|
OnMouseMove(point.X, point.Y);
|
||||||
}
|
}
|
||||||
else if (points == -1)
|
else if (points == -1)
|
||||||
{
|
{
|
||||||
|
@ -468,7 +444,7 @@ namespace OpenTK.Platform.Windows
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Exclude the current position.
|
// Exclude the current position.
|
||||||
Point currentScreenPosition = new Point(mouse.X, mouse.Y);
|
Point currentScreenPosition = new Point(InputDriver.Mouse[0].X, InputDriver.Mouse[0].Y);
|
||||||
Functions.ClientToScreen(handle, ref currentScreenPosition);
|
Functions.ClientToScreen(handle, ref currentScreenPosition);
|
||||||
|
|
||||||
// Find the first move point we've already seen.
|
// Find the first move point we've already seen.
|
||||||
|
@ -497,7 +473,7 @@ namespace OpenTK.Platform.Windows
|
||||||
position.Y -= 65536;
|
position.Y -= 65536;
|
||||||
}
|
}
|
||||||
Functions.ScreenToClient(handle, ref position);
|
Functions.ScreenToClient(handle, ref position);
|
||||||
mouse.Position = position;
|
OnMouseMove(position.X, position.Y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mouse_last_timestamp = timestamp;
|
mouse_last_timestamp = timestamp;
|
||||||
|
@ -510,7 +486,7 @@ namespace OpenTK.Platform.Windows
|
||||||
mouse_outside_window = false;
|
mouse_outside_window = false;
|
||||||
EnableMouseTracking();
|
EnableMouseTracking();
|
||||||
|
|
||||||
MouseEnter(this, EventArgs.Empty);
|
OnMouseEnter(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,64 +495,75 @@ namespace OpenTK.Platform.Windows
|
||||||
mouse_outside_window = true;
|
mouse_outside_window = true;
|
||||||
// Mouse tracking is disabled automatically by the OS
|
// Mouse tracking is disabled automatically by the OS
|
||||||
|
|
||||||
MouseLeave(this, EventArgs.Empty);
|
OnMouseLeave(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleMouseWheel(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleMouseWheel(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese
|
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese
|
||||||
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
|
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
|
||||||
mouse.WheelPrecise += ((long)wParam << 32 >> 48) / 120.0f;
|
OnMouseWheel(0, ((long)wParam << 32 >> 48) / 120.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleMouseHWheel(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
|
{
|
||||||
|
// This is due to inconsistent behavior of the WParam value on 64bit arch, whese
|
||||||
|
// wparam = 0xffffffffff880000 or wparam = 0x00000000ff100000
|
||||||
|
OnMouseWheel(((long)wParam << 32 >> 48) / 120.0f, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleLButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleLButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
Functions.SetCapture(window.Handle);
|
Functions.SetCapture(window.Handle);
|
||||||
mouse[MouseButton.Left] = true;
|
OnMouseDown(MouseButton.Left);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleMButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleMButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
Functions.SetCapture(window.Handle);
|
Functions.SetCapture(window.Handle);
|
||||||
mouse[MouseButton.Middle] = true;
|
OnMouseDown(MouseButton.Middle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleRButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleRButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
Functions.SetCapture(window.Handle);
|
Functions.SetCapture(window.Handle);
|
||||||
mouse[MouseButton.Right] = true;
|
OnMouseDown(MouseButton.Right);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleXButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleXButtonDown(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
Functions.SetCapture(window.Handle);
|
Functions.SetCapture(window.Handle);
|
||||||
mouse[((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ?
|
MouseButton button =
|
||||||
MouseButton.Button1 : MouseButton.Button2] = true;
|
((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ?
|
||||||
|
MouseButton.Button1 : MouseButton.Button2;
|
||||||
|
OnMouseDown(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleLButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleLButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
Functions.ReleaseCapture();
|
Functions.ReleaseCapture();
|
||||||
mouse[MouseButton.Left] = false;
|
OnMouseUp(MouseButton.Left);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleMButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleMButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
Functions.ReleaseCapture();
|
Functions.ReleaseCapture();
|
||||||
mouse[MouseButton.Middle] = false;
|
OnMouseUp(MouseButton.Middle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleRButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleRButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
Functions.ReleaseCapture();
|
Functions.ReleaseCapture();
|
||||||
mouse[MouseButton.Right] = false;
|
OnMouseUp(MouseButton.Right);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleXButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleXButtonUp(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
Functions.ReleaseCapture();
|
Functions.ReleaseCapture();
|
||||||
mouse[((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ?
|
MouseButton button =
|
||||||
MouseButton.Button1 : MouseButton.Button2] = false;
|
((wParam.ToInt32() & 0xFFFF0000) >> 16) == 1 ?
|
||||||
|
MouseButton.Button1 : MouseButton.Button2;
|
||||||
|
OnMouseUp(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleKeyboard(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleKeyboard(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
|
@ -593,33 +580,28 @@ namespace OpenTK.Platform.Windows
|
||||||
// In this case, both keys will be reported as pressed.
|
// In this case, both keys will be reported as pressed.
|
||||||
|
|
||||||
bool extended = (lParam.ToInt64() & ExtendedBit) != 0;
|
bool extended = (lParam.ToInt64() & ExtendedBit) != 0;
|
||||||
short scancode = (short)((lParam.ToInt64() >> 16) & 0xFF);
|
short scancode = (short)((lParam.ToInt64() >> 16) & 0xff);
|
||||||
|
//ushort repeat_count = unchecked((ushort)((ulong)lParam.ToInt64() & 0xffffu));
|
||||||
VirtualKeys vkey = (VirtualKeys)wParam;
|
VirtualKeys vkey = (VirtualKeys)wParam;
|
||||||
bool is_valid;
|
bool is_valid;
|
||||||
Key key = WinKeyMap.TranslateKey(scancode, vkey, extended, false, out is_valid);
|
Key key = WinKeyMap.TranslateKey(scancode, vkey, extended, false, out is_valid);
|
||||||
|
|
||||||
if (is_valid)
|
if (is_valid)
|
||||||
{
|
{
|
||||||
keyboard.SetKey(key, (byte)scancode, pressed);
|
|
||||||
|
|
||||||
if (pressed)
|
if (pressed)
|
||||||
{
|
{
|
||||||
key_down.Key = key;
|
//OnKeyDown(key, repeat_count > 0);
|
||||||
key_down.Modifiers = keyboard.GetModifiers();
|
OnKeyDown(key, KeyboardState[key]);
|
||||||
KeyDown(this, key_down);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
key_up.Key = key;
|
OnKeyUp(key);
|
||||||
key_up.Modifiers = keyboard.GetModifiers();
|
|
||||||
KeyUp(this, key_up);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleKillFocus(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleKillFocus(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
{
|
{
|
||||||
keyboard.ClearKeys();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleCreate(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
void HandleCreate(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
|
@ -644,7 +626,7 @@ namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
System.ComponentModel.CancelEventArgs e = new System.ComponentModel.CancelEventArgs();
|
System.ComponentModel.CancelEventArgs e = new System.ComponentModel.CancelEventArgs();
|
||||||
|
|
||||||
Closing(this, e);
|
OnClosing(e);
|
||||||
|
|
||||||
if (!e.Cancel)
|
if (!e.Cancel)
|
||||||
{
|
{
|
||||||
|
@ -663,7 +645,7 @@ namespace OpenTK.Platform.Windows
|
||||||
window.Dispose();
|
window.Dispose();
|
||||||
child_window.Dispose();
|
child_window.Dispose();
|
||||||
|
|
||||||
Closed(this, EventArgs.Empty);
|
OnClosed(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -731,6 +713,10 @@ namespace OpenTK.Platform.Windows
|
||||||
HandleMouseWheel(handle, message, wParam, lParam);
|
HandleMouseWheel(handle, message, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WindowMessage.MOUSEHWHEEL:
|
||||||
|
HandleMouseHWheel(handle, message, wParam, lParam);
|
||||||
|
break;
|
||||||
|
|
||||||
case WindowMessage.LBUTTONDOWN:
|
case WindowMessage.LBUTTONDOWN:
|
||||||
HandleLButtonDown(handle, message, wParam, lParam);
|
HandleLButtonDown(handle, message, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
@ -927,7 +913,6 @@ namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
suppress_resize++;
|
suppress_resize++;
|
||||||
WindowBorder = WindowBorder.Hidden;
|
WindowBorder = WindowBorder.Hidden;
|
||||||
ProcessEvents();
|
|
||||||
suppress_resize--;
|
suppress_resize--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -938,7 +923,6 @@ namespace OpenTK.Platform.Windows
|
||||||
deferred_window_border.HasValue ? deferred_window_border.Value :
|
deferred_window_border.HasValue ? deferred_window_border.Value :
|
||||||
previous_window_border.HasValue ? previous_window_border.Value :
|
previous_window_border.HasValue ? previous_window_border.Value :
|
||||||
WindowBorder;
|
WindowBorder;
|
||||||
ProcessEvents();
|
|
||||||
suppress_resize--;
|
suppress_resize--;
|
||||||
deferred_window_border = previous_window_border = null;
|
deferred_window_border = previous_window_border = null;
|
||||||
}
|
}
|
||||||
|
@ -947,7 +931,6 @@ namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
suppress_resize++;
|
suppress_resize++;
|
||||||
WindowState = WindowState.Normal;
|
WindowState = WindowState.Normal;
|
||||||
ProcessEvents();
|
|
||||||
suppress_resize--;
|
suppress_resize--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,7 +960,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region Bounds
|
#region Bounds
|
||||||
|
|
||||||
public Rectangle Bounds
|
public override Rectangle Bounds
|
||||||
{
|
{
|
||||||
get { return bounds; }
|
get { return bounds; }
|
||||||
set
|
set
|
||||||
|
@ -991,7 +974,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region Location
|
#region Location
|
||||||
|
|
||||||
public Point Location
|
public override Point Location
|
||||||
{
|
{
|
||||||
get { return Bounds.Location; }
|
get { return Bounds.Location; }
|
||||||
set
|
set
|
||||||
|
@ -1005,7 +988,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region Size
|
#region Size
|
||||||
|
|
||||||
public Size Size
|
public override Size Size
|
||||||
{
|
{
|
||||||
get { return Bounds.Size; }
|
get { return Bounds.Size; }
|
||||||
set
|
set
|
||||||
|
@ -1017,36 +1000,13 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ClientRectangle
|
|
||||||
|
|
||||||
public Rectangle ClientRectangle
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (client_rectangle.Width == 0)
|
|
||||||
client_rectangle.Width = 1;
|
|
||||||
if (client_rectangle.Height == 0)
|
|
||||||
client_rectangle.Height = 1;
|
|
||||||
return client_rectangle;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
WindowStyle style = (WindowStyle)Functions.GetWindowLong(window.Handle, GetWindowLongOffsets.STYLE);
|
|
||||||
Win32Rectangle rect = Win32Rectangle.From(value);
|
|
||||||
Functions.AdjustWindowRect(ref rect, style, false);
|
|
||||||
Size = new Size(rect.Width, rect.Height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ClientSize
|
#region ClientSize
|
||||||
|
|
||||||
public Size ClientSize
|
public override Size ClientSize
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ClientRectangle.Size;
|
return client_rectangle.Size;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
@ -1059,49 +1019,9 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Width
|
|
||||||
|
|
||||||
public int Width
|
|
||||||
{
|
|
||||||
get { return ClientRectangle.Width; }
|
|
||||||
set { ClientRectangle = new Rectangle(0, 0, value, Height); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Height
|
|
||||||
|
|
||||||
public int Height
|
|
||||||
{
|
|
||||||
get { return ClientRectangle.Height; }
|
|
||||||
set { ClientRectangle = new Rectangle(0, 0, Width, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region X
|
|
||||||
|
|
||||||
public int X
|
|
||||||
{
|
|
||||||
get { return Location.X; }
|
|
||||||
set { Location = new Point(value, Y); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Y
|
|
||||||
|
|
||||||
public int Y
|
|
||||||
{
|
|
||||||
get { return Location.Y; }
|
|
||||||
set { Location = new Point(X, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Icon
|
#region Icon
|
||||||
|
|
||||||
public Icon Icon
|
public override Icon Icon
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1117,7 +1037,7 @@ namespace OpenTK.Platform.Windows
|
||||||
Functions.SendMessage(window.Handle, WindowMessage.SETICON, (IntPtr)0, icon == null ? IntPtr.Zero : value.Handle);
|
Functions.SendMessage(window.Handle, WindowMessage.SETICON, (IntPtr)0, icon == null ? IntPtr.Zero : value.Handle);
|
||||||
Functions.SendMessage(window.Handle, WindowMessage.SETICON, (IntPtr)1, icon == null ? IntPtr.Zero : value.Handle);
|
Functions.SendMessage(window.Handle, WindowMessage.SETICON, (IntPtr)1, icon == null ? IntPtr.Zero : value.Handle);
|
||||||
}
|
}
|
||||||
IconChanged(this, EventArgs.Empty);
|
OnIconChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1046,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region Focused
|
#region Focused
|
||||||
|
|
||||||
public bool Focused
|
public override bool Focused
|
||||||
{
|
{
|
||||||
get { return focused; }
|
get { return focused; }
|
||||||
}
|
}
|
||||||
|
@ -1136,7 +1056,7 @@ namespace OpenTK.Platform.Windows
|
||||||
#region Title
|
#region Title
|
||||||
|
|
||||||
StringBuilder sb_title = new StringBuilder(256);
|
StringBuilder sb_title = new StringBuilder(256);
|
||||||
public string Title
|
public override string Title
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1151,7 +1071,7 @@ namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
if (!Functions.SetWindowText(window.Handle, value))
|
if (!Functions.SetWindowText(window.Handle, value))
|
||||||
Debug.Print("Failed to change window title (window:{0}, new title:{1}, reason:{2}).", window.Handle, value, Marshal.GetLastWin32Error());
|
Debug.Print("Failed to change window title (window:{0}, new title:{1}, reason:{2}).", window.Handle, value, Marshal.GetLastWin32Error());
|
||||||
TitleChanged(this, EventArgs.Empty);
|
OnTitleChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1160,7 +1080,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region Visible
|
#region Visible
|
||||||
|
|
||||||
public bool Visible
|
public override bool Visible
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1184,7 +1104,7 @@ namespace OpenTK.Platform.Windows
|
||||||
Functions.ShowWindow(window.Handle, ShowWindowCommand.HIDE);
|
Functions.ShowWindow(window.Handle, ShowWindowCommand.HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
VisibleChanged(this, EventArgs.Empty);
|
OnVisibleChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1193,13 +1113,13 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region Exists
|
#region Exists
|
||||||
|
|
||||||
public bool Exists { get { return exists; } }
|
public override bool Exists { get { return exists; } }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Cursor
|
#region Cursor
|
||||||
|
|
||||||
public MouseCursor Cursor
|
public override MouseCursor Cursor
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1271,7 +1191,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region CursorVisible
|
#region CursorVisible
|
||||||
|
|
||||||
public bool CursorVisible
|
public override bool CursorVisible
|
||||||
{
|
{
|
||||||
get { return cursor_visible_count >= 0; } // Not used
|
get { return cursor_visible_count >= 0; } // Not used
|
||||||
set
|
set
|
||||||
|
@ -1303,7 +1223,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region Close
|
#region Close
|
||||||
|
|
||||||
public void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
Functions.PostMessage(window.Handle, WindowMessage.CLOSE, IntPtr.Zero, IntPtr.Zero);
|
Functions.PostMessage(window.Handle, WindowMessage.CLOSE, IntPtr.Zero, IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
@ -1312,7 +1232,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region public WindowState WindowState
|
#region public WindowState WindowState
|
||||||
|
|
||||||
public WindowState WindowState
|
public override WindowState WindowState
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1325,12 +1245,12 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
ShowWindowCommand command = 0;
|
ShowWindowCommand command = 0;
|
||||||
bool exiting_fullscreen = false;
|
bool exiting_fullscreen = false;
|
||||||
borderless_maximized_window_state = false;
|
|
||||||
|
|
||||||
switch (value)
|
switch (value)
|
||||||
{
|
{
|
||||||
case WindowState.Normal:
|
case WindowState.Normal:
|
||||||
command = ShowWindowCommand.RESTORE;
|
command = ShowWindowCommand.RESTORE;
|
||||||
|
borderless_maximized_window_state = false;
|
||||||
|
|
||||||
// If we are leaving fullscreen mode we need to restore the border.
|
// If we are leaving fullscreen mode we need to restore the border.
|
||||||
if (WindowState == WindowState.Fullscreen)
|
if (WindowState == WindowState.Fullscreen)
|
||||||
|
@ -1358,6 +1278,7 @@ namespace OpenTK.Platform.Windows
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
borderless_maximized_window_state = false;
|
||||||
command = ShowWindowCommand.MAXIMIZE;
|
command = ShowWindowCommand.MAXIMIZE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1406,7 +1327,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region public WindowBorder WindowBorder
|
#region public WindowBorder WindowBorder
|
||||||
|
|
||||||
public WindowBorder WindowBorder
|
public override WindowBorder WindowBorder
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1500,7 +1421,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region PointToClient
|
#region PointToClient
|
||||||
|
|
||||||
public Point PointToClient(Point point)
|
public override Point PointToClient(Point point)
|
||||||
{
|
{
|
||||||
if (!Functions.ScreenToClient(window.Handle, ref point))
|
if (!Functions.ScreenToClient(window.Handle, ref point))
|
||||||
throw new InvalidOperationException(String.Format(
|
throw new InvalidOperationException(String.Format(
|
||||||
|
@ -1514,7 +1435,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region PointToScreen
|
#region PointToScreen
|
||||||
|
|
||||||
public Point PointToScreen(Point point)
|
public override Point PointToScreen(Point point)
|
||||||
{
|
{
|
||||||
if (!Functions.ClientToScreen(window.Handle, ref point))
|
if (!Functions.ClientToScreen(window.Handle, ref point))
|
||||||
throw new InvalidOperationException(String.Format(
|
throw new InvalidOperationException(String.Format(
|
||||||
|
@ -1526,27 +1447,6 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Events
|
|
||||||
|
|
||||||
public event EventHandler<EventArgs> Move = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Resize = delegate { };
|
|
||||||
public event EventHandler<System.ComponentModel.CancelEventArgs> Closing = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Closed = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Disposed = delegate { };
|
|
||||||
public event EventHandler<EventArgs> IconChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> TitleChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> VisibleChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> FocusedChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> WindowBorderChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> WindowStateChanged = delegate { };
|
|
||||||
public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyDown = delegate { };
|
|
||||||
public event EventHandler<KeyPressEventArgs> KeyPress = delegate { };
|
|
||||||
public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyUp = delegate { };
|
|
||||||
public event EventHandler<EventArgs> MouseEnter = delegate { };
|
|
||||||
public event EventHandler<EventArgs> MouseLeave = delegate { };
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region INativeGLWindow Members
|
#region INativeGLWindow Members
|
||||||
|
@ -1554,8 +1454,9 @@ namespace OpenTK.Platform.Windows
|
||||||
#region public void ProcessEvents()
|
#region public void ProcessEvents()
|
||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
public void ProcessEvents()
|
public override void ProcessEvents()
|
||||||
{
|
{
|
||||||
|
base.ProcessEvents();
|
||||||
while (Functions.PeekMessage(ref msg, IntPtr.Zero, 0, 0, PeekMessageFlags.Remove))
|
while (Functions.PeekMessage(ref msg, IntPtr.Zero, 0, 0, PeekMessageFlags.Remove))
|
||||||
{
|
{
|
||||||
Functions.TranslateMessage(ref msg);
|
Functions.TranslateMessage(ref msg);
|
||||||
|
@ -1565,18 +1466,9 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public IInputDriver InputDriver
|
|
||||||
|
|
||||||
public IInputDriver InputDriver
|
|
||||||
{
|
|
||||||
get { return this; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region public IWindowInfo WindowInfo
|
#region public IWindowInfo WindowInfo
|
||||||
|
|
||||||
public IWindowInfo WindowInfo
|
public override IWindowInfo WindowInfo
|
||||||
{
|
{
|
||||||
get { return child_window; }
|
get { return child_window; }
|
||||||
}
|
}
|
||||||
|
@ -1585,62 +1477,9 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IInputDriver Members
|
|
||||||
|
|
||||||
public void Poll()
|
|
||||||
{
|
|
||||||
if (joystick_driver is WinMMJoystick)
|
|
||||||
(joystick_driver as WinMMJoystick).Poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IKeyboardDriver Members
|
|
||||||
|
|
||||||
public IList<KeyboardDevice> Keyboard
|
|
||||||
{
|
|
||||||
get { return keyboards; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyboardState GetState()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyboardState GetState(int index)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IMouseDriver Members
|
|
||||||
|
|
||||||
public IList<MouseDevice> Mouse
|
|
||||||
{
|
|
||||||
get { return mice; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IJoystickDriver Members
|
|
||||||
|
|
||||||
public IList<JoystickDevice> Joysticks
|
|
||||||
{
|
|
||||||
get { return joystick_driver.Joysticks; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IDisposable Members
|
#region IDisposable Members
|
||||||
|
|
||||||
public void Dispose()
|
protected override void Dispose(bool calledManually)
|
||||||
{
|
|
||||||
this.Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dispose(bool calledManually)
|
|
||||||
{
|
{
|
||||||
if (!disposed)
|
if (!disposed)
|
||||||
{
|
{
|
||||||
|
@ -1662,16 +1501,11 @@ namespace OpenTK.Platform.Windows
|
||||||
Debug.Print("[Warning] INativeWindow leaked ({0}). Did you forget to call INativeWindow.Dispose()?", this);
|
Debug.Print("[Warning] INativeWindow leaked ({0}). Did you forget to call INativeWindow.Dispose()?", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Disposed(this, EventArgs.Empty);
|
OnDisposed(EventArgs.Empty);
|
||||||
disposed = true;
|
disposed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~WinGLNative()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
if (is_valid)
|
if (is_valid)
|
||||||
{
|
{
|
||||||
keyboard.SetKeyState(key, (byte)scancode, pressed);
|
keyboard.SetKeyState(key, pressed);
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -227,7 +227,10 @@ namespace OpenTK.Platform.Windows
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((raw.ButtonFlags & RawInputMouseState.WHEEL) != 0)
|
if ((raw.ButtonFlags & RawInputMouseState.WHEEL) != 0)
|
||||||
mouse.WheelPrecise += (short)raw.ButtonData / 120.0f;
|
mouse.SetScrollRelative(0, (short)raw.ButtonData / 120.0f);
|
||||||
|
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.HWHEEL) != 0)
|
||||||
|
mouse.SetScrollRelative((short)raw.ButtonData / 120.0f, 0);
|
||||||
|
|
||||||
if ((raw.Flags & RawMouseFlags.MOUSE_MOVE_ABSOLUTE) != 0)
|
if ((raw.Flags & RawMouseFlags.MOUSE_MOVE_ABSOLUTE) != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -266,7 +266,14 @@ namespace OpenTK.Platform.X11
|
||||||
static string[] EntryPointNames = new string[]
|
static string[] EntryPointNames = new string[]
|
||||||
{
|
{
|
||||||
"glXCreateContextAttribs",
|
"glXCreateContextAttribs",
|
||||||
|
"glXSwapIntervalEXT",
|
||||||
|
"glXGetSwapIntervalEXT",
|
||||||
|
"glXSwapIntervalMESA",
|
||||||
|
"glXGetSwapIntervalMESA",
|
||||||
|
"glXSwapIntervalOML",
|
||||||
|
"glXGetSwapIntervalOML",
|
||||||
"glXSwapIntervalSGI",
|
"glXSwapIntervalSGI",
|
||||||
|
"glXGetSwapIntervalSGI",
|
||||||
};
|
};
|
||||||
static IntPtr[] EntryPoints = new IntPtr[EntryPointNames.Length];
|
static IntPtr[] EntryPoints = new IntPtr[EntryPointNames.Length];
|
||||||
|
|
||||||
|
@ -405,6 +412,36 @@ namespace OpenTK.Platform.X11
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public partial class Ext
|
||||||
|
{
|
||||||
|
[AutoGenerated(EntryPoint = "glXSwapIntervalEXT")]
|
||||||
|
public static ErrorCode SwapInterval(int interval)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
[AutoGenerated(EntryPoint = "glXGetSwapIntervalEXT")]
|
||||||
|
public static int GetSwapInterval()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public partial class Mesa
|
||||||
|
{
|
||||||
|
[AutoGenerated(EntryPoint = "glXSwapIntervalMESA")]
|
||||||
|
public static ErrorCode SwapInterval(int interval)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
[AutoGenerated(EntryPoint = "glXGetSwapIntervalMESA")]
|
||||||
|
public static int GetSwapInterval()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public partial class Sgi
|
public partial class Sgi
|
||||||
{
|
{
|
||||||
[AutoGenerated(EntryPoint = "glXSwapIntervalSGI")]
|
[AutoGenerated(EntryPoint = "glXSwapIntervalSGI")]
|
||||||
|
@ -412,6 +449,12 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AutoGenerated(EntryPoint = "glXGetSwapIntervalSGI")]
|
||||||
|
public static int GetSwapInterval()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Slot(0)]
|
[Slot(0)]
|
||||||
|
@ -419,7 +462,22 @@ namespace OpenTK.Platform.X11
|
||||||
internal unsafe static extern IntPtr glXCreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
|
internal unsafe static extern IntPtr glXCreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
|
||||||
[Slot(1)]
|
[Slot(1)]
|
||||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||||
internal static extern IntPtr glXSwapIntervalSGI(int interval);
|
internal static extern ErrorCode glXSwapIntervalEXT(int interval);
|
||||||
|
[Slot(2)]
|
||||||
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||||
|
internal static extern int glXGetSwapIntervalEXT();
|
||||||
|
[Slot(3)]
|
||||||
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||||
|
internal static extern ErrorCode glXSwapIntervalMESA(int interval);
|
||||||
|
[Slot(4)]
|
||||||
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||||
|
internal static extern int glXGetSwapIntervalMESA();
|
||||||
|
[Slot(5)]
|
||||||
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||||
|
internal static extern ErrorCode glXSwapIntervalSGI(int interval);
|
||||||
|
[Slot(6)]
|
||||||
|
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||||
|
internal static extern int glXGetSwapIntervalSGI();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -1707,7 +1707,7 @@ namespace OpenTK.Platform.X11
|
||||||
public double root_y;
|
public double root_y;
|
||||||
public double event_x;
|
public double event_x;
|
||||||
public double event_y;
|
public double event_y;
|
||||||
public int flags;
|
public XIEventFlags flags;
|
||||||
public XIButtonState buttons;
|
public XIButtonState buttons;
|
||||||
public XIValuatorState valuators;
|
public XIValuatorState valuators;
|
||||||
public XIModifierState mods;
|
public XIModifierState mods;
|
||||||
|
@ -1828,4 +1828,32 @@ namespace OpenTK.Platform.X11
|
||||||
RawButtonReleaseMask = (1 << (int)XIEventType.RawButtonRelease),
|
RawButtonReleaseMask = (1 << (int)XIEventType.RawButtonRelease),
|
||||||
RawMotionMask = (1 << (int)XIEventType.RawMotion),
|
RawMotionMask = (1 << (int)XIEventType.RawMotion),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
enum XIKeyEventFlags
|
||||||
|
{
|
||||||
|
Repeat = (1 << 16),
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
enum XIPointerEventFlags
|
||||||
|
{
|
||||||
|
Emulated = (1 << 16),
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
enum XITouchEventFlags
|
||||||
|
{
|
||||||
|
PendingEnd = (1 << 16),
|
||||||
|
EmulatingPointer = (1 << 17),
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
enum XIEventFlags
|
||||||
|
{
|
||||||
|
KeyRepeat = XIKeyEventFlags.Repeat,
|
||||||
|
PointerEmulated = XIPointerEventFlags.Emulated,
|
||||||
|
TouchPendingEnd = XITouchEventFlags.PendingEnd,
|
||||||
|
TouchEmulatingPointer = XITouchEventFlags.EmulatingPointer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,10 +29,13 @@ namespace OpenTK.Platform.X11
|
||||||
// current on window originating from a different display.
|
// current on window originating from a different display.
|
||||||
IntPtr display;
|
IntPtr display;
|
||||||
X11WindowInfo currentWindow;
|
X11WindowInfo currentWindow;
|
||||||
bool vsync_supported;
|
bool vsync_ext_supported;
|
||||||
|
bool vsync_mesa_supported;
|
||||||
|
bool vsync_sgi_supported;
|
||||||
bool vsync_tear_supported;
|
bool vsync_tear_supported;
|
||||||
int swap_interval = 1; // As defined in GLX_SGI_swap_control
|
int sgi_swap_interval = 1; // As defined in GLX_SGI_swap_control
|
||||||
readonly X11GraphicsMode ModeSelector = new X11GraphicsMode();
|
readonly X11GraphicsMode ModeSelector = new X11GraphicsMode();
|
||||||
|
string extensions = null;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -232,7 +235,7 @@ namespace OpenTK.Platform.X11
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SupportsExtension(IntPtr display, X11WindowInfo window, string e)
|
bool SupportsExtension(IntPtr display, X11WindowInfo window, string e)
|
||||||
{
|
{
|
||||||
if (window == null)
|
if (window == null)
|
||||||
throw new ArgumentNullException("window");
|
throw new ArgumentNullException("window");
|
||||||
|
@ -241,15 +244,17 @@ namespace OpenTK.Platform.X11
|
||||||
if (window.Display != display)
|
if (window.Display != display)
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
|
||||||
string extensions = null;
|
if (String.IsNullOrEmpty(extensions))
|
||||||
|
{
|
||||||
using (new XLock(display))
|
using (new XLock(display))
|
||||||
{
|
{
|
||||||
extensions = Glx.QueryExtensionsString(display, window.Screen);
|
extensions = Glx.QueryExtensionsString(display, window.Screen);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return !String.IsNullOrEmpty(extensions) && extensions.Contains(e);
|
return !String.IsNullOrEmpty(extensions) && extensions.Contains(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool SupportsCreateContextAttribs(IntPtr display, X11WindowInfo window)
|
bool SupportsCreateContextAttribs(IntPtr display, X11WindowInfo window)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
SupportsExtension(display, window, "GLX_ARB_create_context") &&
|
SupportsExtension(display, window, "GLX_ARB_create_context") &&
|
||||||
|
@ -354,14 +359,19 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (vsync_supported)
|
using (new XLock(display))
|
||||||
return swap_interval;
|
{
|
||||||
|
if (vsync_ext_supported)
|
||||||
|
return Glx.Ext.GetSwapInterval();
|
||||||
|
else if (vsync_mesa_supported)
|
||||||
|
return Glx.Mesa.GetSwapInterval();
|
||||||
|
else if (vsync_sgi_supported)
|
||||||
|
return sgi_swap_interval;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
set
|
set
|
||||||
{
|
|
||||||
if (vsync_supported)
|
|
||||||
{
|
{
|
||||||
if (value < 0 && !vsync_tear_supported)
|
if (value < 0 && !vsync_tear_supported)
|
||||||
{
|
{
|
||||||
|
@ -370,15 +380,21 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
ErrorCode error_code = 0;
|
ErrorCode error_code = 0;
|
||||||
using (new XLock(Display))
|
using (new XLock(Display))
|
||||||
|
{
|
||||||
|
if (vsync_ext_supported)
|
||||||
|
error_code = Glx.Ext.SwapInterval(value);
|
||||||
|
else if (vsync_mesa_supported)
|
||||||
|
error_code = Glx.Mesa.SwapInterval(value);
|
||||||
|
else if (vsync_sgi_supported)
|
||||||
error_code = Glx.Sgi.SwapInterval(value);
|
error_code = Glx.Sgi.SwapInterval(value);
|
||||||
|
}
|
||||||
|
|
||||||
if (error_code == X11.ErrorCode.NO_ERROR)
|
if (error_code == X11.ErrorCode.NO_ERROR)
|
||||||
swap_interval = value;
|
sgi_swap_interval = value;
|
||||||
else
|
else
|
||||||
Debug.Print("VSync = {0} failed, error code: {1}.", value, error_code);
|
Debug.Print("VSync = {0} failed, error code: {1}.", value, error_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -386,12 +402,23 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
public override void LoadAll()
|
public override void LoadAll()
|
||||||
{
|
{
|
||||||
vsync_supported =
|
vsync_ext_supported =
|
||||||
|
SupportsExtension(display, currentWindow, "GLX_EXT_swap_control") &&
|
||||||
|
Glx.SupportsFunction("glXSwapIntervalEXT") &&
|
||||||
|
Glx.SupportsFunction("glXGetSwapIntervalEXT");
|
||||||
|
vsync_mesa_supported =
|
||||||
|
SupportsExtension(display, currentWindow, "GLX_MESA_swap_control") &&
|
||||||
|
Glx.SupportsFunction("glXSwapIntervalMESA") &&
|
||||||
|
Glx.SupportsFunction("glXGetSwapIntervalMESA");
|
||||||
|
vsync_sgi_supported =
|
||||||
SupportsExtension(display, currentWindow, "GLX_SGI_swap_control") &&
|
SupportsExtension(display, currentWindow, "GLX_SGI_swap_control") &&
|
||||||
Glx.SupportsFunction("glXSwapIntervalSGI");
|
Glx.SupportsFunction("glXSwapIntervalSGI");
|
||||||
|
Debug.Print("Context supports vsync: {0}.",
|
||||||
|
vsync_ext_supported || vsync_mesa_supported || vsync_ext_supported);
|
||||||
|
|
||||||
vsync_tear_supported =
|
vsync_tear_supported =
|
||||||
SupportsExtension(display, currentWindow, "GLX_EXT_swap_control_tear");
|
SupportsExtension(display, currentWindow, "GLX_EXT_swap_control_tear");
|
||||||
Debug.Print("Context supports vsync: {0}.", vsync_supported);
|
Debug.Print("Context supports vsync tear: {0}.", vsync_tear_supported);
|
||||||
|
|
||||||
base.LoadAll();
|
base.LoadAll();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace OpenTK.Platform.X11
|
||||||
/// Drives GameWindow on X11.
|
/// Drives GameWindow on X11.
|
||||||
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
|
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal sealed class X11GLNative : INativeWindow, IDisposable
|
internal sealed class X11GLNative : NativeWindowBase
|
||||||
{
|
{
|
||||||
// TODO: Disable screensaver.
|
// TODO: Disable screensaver.
|
||||||
// TODO: What happens if we can't disable decorations through motif?
|
// TODO: What happens if we can't disable decorations through motif?
|
||||||
|
@ -57,11 +57,6 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
X11WindowInfo window = new X11WindowInfo();
|
X11WindowInfo window = new X11WindowInfo();
|
||||||
|
|
||||||
// Legacy input support
|
|
||||||
X11Input driver;
|
|
||||||
KeyboardDevice keyboard;
|
|
||||||
MouseDevice mouse;
|
|
||||||
|
|
||||||
// Window manager hints for fullscreen windows.
|
// Window manager hints for fullscreen windows.
|
||||||
// Not used right now (the code is written, but is not 64bit-correct), but could be useful for older WMs which
|
// Not used right now (the code is written, but is not 64bit-correct), but could be useful for older WMs which
|
||||||
// are not ICCM compliant, but may support MOTIF hints.
|
// are not ICCM compliant, but may support MOTIF hints.
|
||||||
|
@ -116,6 +111,13 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
bool _decorations_hidden = false;
|
bool _decorations_hidden = false;
|
||||||
|
|
||||||
|
// Store previous border and bounds
|
||||||
|
// when switching from WindowState.Normal
|
||||||
|
// to a different state. When switching
|
||||||
|
// back, reset window to these.s
|
||||||
|
WindowBorder _previous_window_border;
|
||||||
|
Size _previous_window_size;
|
||||||
|
|
||||||
MouseCursor cursor = MouseCursor.Default;
|
MouseCursor cursor = MouseCursor.Default;
|
||||||
IntPtr cursorHandle;
|
IntPtr cursorHandle;
|
||||||
bool cursor_visible = true;
|
bool cursor_visible = true;
|
||||||
|
@ -124,14 +126,14 @@ namespace OpenTK.Platform.X11
|
||||||
// Keyboard input
|
// Keyboard input
|
||||||
readonly byte[] ascii = new byte[16];
|
readonly byte[] ascii = new byte[16];
|
||||||
readonly char[] chars = new char[16];
|
readonly char[] chars = new char[16];
|
||||||
readonly KeyPressEventArgs KPEventArgs = new KeyPressEventArgs('\0');
|
|
||||||
readonly KeyboardKeyEventArgs KeyDownEventArgs = new KeyboardKeyEventArgs();
|
|
||||||
readonly KeyboardKeyEventArgs KeyUpEventArgs = new KeyboardKeyEventArgs();
|
|
||||||
|
|
||||||
readonly IntPtr EmptyCursor;
|
readonly IntPtr EmptyCursor;
|
||||||
|
|
||||||
public static bool MouseWarpActive = false;
|
public static bool MouseWarpActive = false;
|
||||||
|
|
||||||
|
readonly bool xi2_supported;
|
||||||
|
readonly int xi2_opcode;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
@ -224,15 +226,26 @@ namespace OpenTK.Platform.X11
|
||||||
e.ConfigureEvent.height = height;
|
e.ConfigureEvent.height = height;
|
||||||
RefreshWindowBounds(ref e);
|
RefreshWindowBounds(ref e);
|
||||||
|
|
||||||
driver = new X11Input(window);
|
|
||||||
keyboard = driver.Keyboard[0];
|
|
||||||
mouse = driver.Mouse[0];
|
|
||||||
|
|
||||||
EmptyCursor = CreateEmptyCursor(window);
|
EmptyCursor = CreateEmptyCursor(window);
|
||||||
|
|
||||||
Debug.WriteLine(String.Format("X11GLNative window created successfully (id: {0}).", Handle));
|
Debug.WriteLine(String.Format("X11GLNative window created successfully (id: {0}).", Handle));
|
||||||
Debug.Unindent();
|
Debug.Unindent();
|
||||||
|
|
||||||
|
// Request that auto-repeat is only set on devices that support it physically.
|
||||||
|
// This typically means that it's turned off for keyboards (which is what we want).
|
||||||
|
// We prefer this method over XAutoRepeatOff/On, because the latter needs to
|
||||||
|
// be reset before the program exits.
|
||||||
|
bool supported;
|
||||||
|
Functions.XkbSetDetectableAutoRepeat(window.Display, true, out supported);
|
||||||
|
|
||||||
|
// The XInput2 extension makes keyboard and mouse handling much easier.
|
||||||
|
// Check whether it is available.
|
||||||
|
xi2_supported = XI2Mouse.IsSupported(window.Display);
|
||||||
|
if (xi2_supported)
|
||||||
|
{
|
||||||
|
xi2_opcode = XI2Mouse.XIOpCode;
|
||||||
|
}
|
||||||
|
|
||||||
exists = true;
|
exists = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -733,7 +746,7 @@ namespace OpenTK.Platform.X11
|
||||||
if (Location != new_location)
|
if (Location != new_location)
|
||||||
{
|
{
|
||||||
bounds.Location = new_location;
|
bounds.Location = new_location;
|
||||||
Move(this, EventArgs.Empty);
|
OnMove(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: width and height denote the internal (client) size.
|
// Note: width and height denote the internal (client) size.
|
||||||
|
@ -744,9 +757,15 @@ namespace OpenTK.Platform.X11
|
||||||
if (Bounds.Size != new_size)
|
if (Bounds.Size != new_size)
|
||||||
{
|
{
|
||||||
bounds.Size = new_size;
|
bounds.Size = new_size;
|
||||||
client_rectangle.Size = new Size(e.ConfigureEvent.width, e.ConfigureEvent.height);
|
|
||||||
|
|
||||||
Resize(this, EventArgs.Empty);
|
// X11 sets the client width/height to 0
|
||||||
|
// when the window is minimized. Many apps
|
||||||
|
// do not expect this and crash, so clamp
|
||||||
|
// minimum width/height to 1 instead.
|
||||||
|
client_rectangle.Size = new Size(
|
||||||
|
Math.Max(e.ConfigureEvent.width, 1),
|
||||||
|
Math.Max(e.ConfigureEvent.height, 1));
|
||||||
|
OnResize(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Debug.Print("[X11] Window bounds changed: {0}", bounds);
|
//Debug.Print("[X11] Window bounds changed: {0}", bounds);
|
||||||
|
@ -768,25 +787,15 @@ namespace OpenTK.Platform.X11
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetMouseClamped(MouseDevice mouse, int x, int y,
|
|
||||||
int left, int top, int width, int height)
|
|
||||||
{
|
|
||||||
// Clamp mouse to the specified rectangle.
|
|
||||||
x = Math.Max(x, left);
|
|
||||||
x = Math.Min(x, width);
|
|
||||||
y = Math.Max(y, top);
|
|
||||||
y = Math.Min(y, height);
|
|
||||||
mouse.Position = new Point(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region INativeWindow Members
|
#region INativeWindow Members
|
||||||
|
|
||||||
#region ProcessEvents
|
#region ProcessEvents
|
||||||
|
|
||||||
public void ProcessEvents()
|
public override void ProcessEvents()
|
||||||
{
|
{
|
||||||
|
base.ProcessEvents();
|
||||||
// Process all pending events
|
// Process all pending events
|
||||||
while (Exists && window != null)
|
while (Exists && window != null)
|
||||||
{
|
{
|
||||||
|
@ -805,7 +814,7 @@ namespace OpenTK.Platform.X11
|
||||||
bool previous_visible = visible;
|
bool previous_visible = visible;
|
||||||
visible = true;
|
visible = true;
|
||||||
if (visible != previous_visible)
|
if (visible != previous_visible)
|
||||||
VisibleChanged(this, EventArgs.Empty);
|
OnVisibleChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -814,7 +823,7 @@ namespace OpenTK.Platform.X11
|
||||||
bool previous_visible = visible;
|
bool previous_visible = visible;
|
||||||
visible = false;
|
visible = false;
|
||||||
if (visible != previous_visible)
|
if (visible != previous_visible)
|
||||||
VisibleChanged(this, EventArgs.Empty);
|
OnVisibleChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -827,7 +836,7 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
Debug.WriteLine("Exit message received.");
|
Debug.WriteLine("Exit message received.");
|
||||||
CancelEventArgs ce = new CancelEventArgs();
|
CancelEventArgs ce = new CancelEventArgs();
|
||||||
Closing(this, ce);
|
OnClosing(ce);
|
||||||
|
|
||||||
if (!ce.Cancel)
|
if (!ce.Cancel)
|
||||||
{
|
{
|
||||||
|
@ -848,7 +857,7 @@ namespace OpenTK.Platform.X11
|
||||||
Debug.WriteLine("Window destroyed");
|
Debug.WriteLine("Window destroyed");
|
||||||
exists = false;
|
exists = false;
|
||||||
|
|
||||||
Closed(this, EventArgs.Empty);
|
OnClosed(EventArgs.Empty);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -860,26 +869,18 @@ namespace OpenTK.Platform.X11
|
||||||
case XEventName.KeyRelease:
|
case XEventName.KeyRelease:
|
||||||
bool pressed = e.type == XEventName.KeyPress;
|
bool pressed = e.type == XEventName.KeyPress;
|
||||||
Key key;
|
Key key;
|
||||||
if (driver.TranslateKey(ref e.KeyEvent, out key))
|
if (X11KeyMap.TranslateKey(ref e.KeyEvent, out key))
|
||||||
{
|
{
|
||||||
// Update legacy GameWindow.Keyboard API:
|
|
||||||
keyboard.SetKey(key, (uint)e.KeyEvent.keycode, pressed);
|
|
||||||
|
|
||||||
if (pressed)
|
if (pressed)
|
||||||
{
|
{
|
||||||
// Raise KeyDown event
|
// Raise KeyDown event
|
||||||
KeyDownEventArgs.Key = key;
|
bool is_repeat = KeyboardState[key];
|
||||||
KeyDownEventArgs.ScanCode = (uint)e.KeyEvent.keycode;
|
OnKeyDown(key, is_repeat);
|
||||||
KeyDownEventArgs.Modifiers = keyboard.GetModifiers();
|
|
||||||
KeyDown(this, KeyDownEventArgs);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Raise KeyUp event
|
// Raise KeyUp event
|
||||||
KeyUpEventArgs.Key = key;
|
OnKeyUp(key);
|
||||||
KeyUpEventArgs.ScanCode = (uint)e.KeyEvent.keycode;
|
|
||||||
KeyUpEventArgs.Modifiers = keyboard.GetModifiers();
|
|
||||||
KeyUp(this, KeyUpEventArgs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pressed)
|
if (pressed)
|
||||||
|
@ -895,8 +896,7 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
if (!Char.IsControl(chars[i]))
|
if (!Char.IsControl(chars[i]))
|
||||||
{
|
{
|
||||||
KPEventArgs.KeyChar = chars[i];
|
OnKeyPress(chars[i]);
|
||||||
KeyPress(this, KPEventArgs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -910,7 +910,7 @@ namespace OpenTK.Platform.X11
|
||||||
// to the dead center of the window. Fortunately, this situation
|
// to the dead center of the window. Fortunately, this situation
|
||||||
// is very very uncommon. Todo: Can this be remedied?
|
// is very very uncommon. Todo: Can this be remedied?
|
||||||
int x = e.MotionEvent.x;
|
int x = e.MotionEvent.x;
|
||||||
int y =e.MotionEvent.y;
|
int y = e.MotionEvent.y;
|
||||||
// TODO: Have offset as a stored field, only update it when the window moves
|
// TODO: Have offset as a stored field, only update it when the window moves
|
||||||
// The middle point cannot be the average of the Bounds.left/right/top/bottom,
|
// The middle point cannot be the average of the Bounds.left/right/top/bottom,
|
||||||
// because these fields take into account window decoration (borders, etc),
|
// because these fields take into account window decoration (borders, etc),
|
||||||
|
@ -929,10 +929,9 @@ namespace OpenTK.Platform.X11
|
||||||
}
|
}
|
||||||
else if (!CursorVisible)
|
else if (!CursorVisible)
|
||||||
{
|
{
|
||||||
SetMouseClamped(mouse,
|
OnMouseMove(
|
||||||
mouse.X + x - mouse_rel_x,
|
MathHelper.Clamp(MouseState.X + x - mouse_rel_x, 0, Width),
|
||||||
mouse.Y + y - mouse_rel_y,
|
MathHelper.Clamp(MouseState.Y + y - mouse_rel_y, 0, Height));
|
||||||
0, 0, Width, Height);
|
|
||||||
mouse_rel_x = x;
|
mouse_rel_x = x;
|
||||||
mouse_rel_y = y;
|
mouse_rel_y = y;
|
||||||
|
|
||||||
|
@ -942,16 +941,42 @@ namespace OpenTK.Platform.X11
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetMouseClamped(mouse, x, y, 0, 0, Width, Height);
|
OnMouseMove(
|
||||||
|
MathHelper.Clamp(x, 0, Width),
|
||||||
|
MathHelper.Clamp(y, 0, Height));
|
||||||
mouse_rel_x = x;
|
mouse_rel_x = x;
|
||||||
mouse_rel_y = y;
|
mouse_rel_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case XEventName.ButtonPress:
|
case XEventName.ButtonPress:
|
||||||
|
{
|
||||||
|
int dx, dy;
|
||||||
|
MouseButton button = X11KeyMap.TranslateButton(e.ButtonEvent.button, out dx, out dy);
|
||||||
|
|
||||||
|
if (button != MouseButton.LastButton)
|
||||||
|
{
|
||||||
|
OnMouseDown(button);
|
||||||
|
}
|
||||||
|
else if (dx != 0 || dy != 0)
|
||||||
|
{
|
||||||
|
OnMouseWheel(dx, dy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case XEventName.ButtonRelease:
|
case XEventName.ButtonRelease:
|
||||||
driver.ProcessEvent(ref e);
|
{
|
||||||
|
int dx, dy;
|
||||||
|
MouseButton button = X11KeyMap.TranslateButton(e.ButtonEvent.button, out dx, out dy);
|
||||||
|
|
||||||
|
if (button != MouseButton.LastButton)
|
||||||
|
{
|
||||||
|
OnMouseUp(button);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEventName.FocusIn:
|
case XEventName.FocusIn:
|
||||||
|
@ -959,7 +984,7 @@ namespace OpenTK.Platform.X11
|
||||||
bool previous_focus = has_focus;
|
bool previous_focus = has_focus;
|
||||||
has_focus = true;
|
has_focus = true;
|
||||||
if (has_focus != previous_focus)
|
if (has_focus != previous_focus)
|
||||||
FocusedChanged(this, EventArgs.Empty);
|
OnFocusedChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -968,19 +993,19 @@ namespace OpenTK.Platform.X11
|
||||||
bool previous_focus = has_focus;
|
bool previous_focus = has_focus;
|
||||||
has_focus = false;
|
has_focus = false;
|
||||||
if (has_focus != previous_focus)
|
if (has_focus != previous_focus)
|
||||||
FocusedChanged(this, EventArgs.Empty);
|
OnFocusedChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEventName.LeaveNotify:
|
case XEventName.LeaveNotify:
|
||||||
if (CursorVisible)
|
if (CursorVisible)
|
||||||
{
|
{
|
||||||
MouseLeave(this, EventArgs.Empty);
|
OnMouseLeave(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEventName.EnterNotify:
|
case XEventName.EnterNotify:
|
||||||
MouseEnter(this, EventArgs.Empty);
|
OnMouseEnter(EventArgs.Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEventName.MappingNotify:
|
case XEventName.MappingNotify:
|
||||||
|
@ -995,7 +1020,7 @@ namespace OpenTK.Platform.X11
|
||||||
case XEventName.PropertyNotify:
|
case XEventName.PropertyNotify:
|
||||||
if (e.PropertyEvent.atom == _atom_net_wm_state)
|
if (e.PropertyEvent.atom == _atom_net_wm_state)
|
||||||
{
|
{
|
||||||
WindowStateChanged(this, EventArgs.Empty);
|
OnWindowStateChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (e.PropertyEvent.atom == _atom_net_frame_extents)
|
//if (e.PropertyEvent.atom == _atom_net_frame_extents)
|
||||||
|
@ -1015,7 +1040,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region Bounds
|
#region Bounds
|
||||||
|
|
||||||
public Rectangle Bounds
|
public override Rectangle Bounds
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1061,50 +1086,18 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Location
|
#region ClientSize
|
||||||
|
|
||||||
public Point Location
|
public override Size ClientSize
|
||||||
{
|
|
||||||
get { return Bounds.Location; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Bounds = new Rectangle(value, Bounds.Size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Size
|
|
||||||
|
|
||||||
public Size Size
|
|
||||||
{
|
|
||||||
get { return Bounds.Size; }
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Bounds = new Rectangle(Bounds.Location, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ClientRectangle
|
|
||||||
|
|
||||||
public Rectangle ClientRectangle
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (client_rectangle.Width == 0)
|
return client_rectangle.Size;
|
||||||
client_rectangle.Width = 1;
|
|
||||||
if (client_rectangle.Height == 0)
|
|
||||||
client_rectangle.Height = 1;
|
|
||||||
return client_rectangle;
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
using (new XLock(window.Display))
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
Functions.XMoveWindow(window.Display, window.Handle,
|
|
||||||
value.X, value.Y);
|
|
||||||
Functions.XResizeWindow(window.Display, window.Handle,
|
Functions.XResizeWindow(window.Display, window.Handle,
|
||||||
value.Width, value.Height);
|
value.Width, value.Height);
|
||||||
}
|
}
|
||||||
|
@ -1114,65 +1107,9 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ClientSize
|
|
||||||
|
|
||||||
public Size ClientSize
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ClientRectangle.Size;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ClientRectangle = new Rectangle(Point.Empty, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Width
|
|
||||||
|
|
||||||
public int Width
|
|
||||||
{
|
|
||||||
get { return ClientSize.Width; }
|
|
||||||
set { ClientSize = new Size(value, Height); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Height
|
|
||||||
|
|
||||||
public int Height
|
|
||||||
{
|
|
||||||
get { return ClientSize.Height; }
|
|
||||||
set { ClientSize = new Size(Width, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region X
|
|
||||||
|
|
||||||
public int X
|
|
||||||
{
|
|
||||||
get { return Location.X; }
|
|
||||||
set { Location = new Point(value, Y); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Y
|
|
||||||
|
|
||||||
public int Y
|
|
||||||
{
|
|
||||||
get { return Location.Y; }
|
|
||||||
set { Location = new Point(X, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Icon
|
#region Icon
|
||||||
|
|
||||||
public Icon Icon
|
public override Icon Icon
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1238,7 +1175,7 @@ namespace OpenTK.Platform.X11
|
||||||
}
|
}
|
||||||
|
|
||||||
icon = value;
|
icon = value;
|
||||||
IconChanged(this, EventArgs.Empty);
|
OnIconChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,7 +1183,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region Focused
|
#region Focused
|
||||||
|
|
||||||
public bool Focused
|
public override bool Focused
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1258,7 +1195,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region WindowState
|
#region WindowState
|
||||||
|
|
||||||
public OpenTK.WindowState WindowState
|
public override OpenTK.WindowState WindowState
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1319,44 +1256,86 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
OpenTK.WindowState current_state = this.WindowState;
|
OpenTK.WindowState current_state = this.WindowState;
|
||||||
|
|
||||||
|
// When switching away from normal state, store
|
||||||
|
// the "normal" border and size. These will be used
|
||||||
|
// for restoring to normal state.
|
||||||
|
if (current_state == OpenTK.WindowState.Normal)
|
||||||
|
{
|
||||||
|
_previous_window_border = WindowBorder;
|
||||||
|
_previous_window_size = ClientSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (current_state == value)
|
if (current_state == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Debug.Print("GameWindow {0} changing WindowState from {1} to {2}.", window.Handle.ToString(),
|
Debug.Print("GameWindow {0} changing WindowState from {1} to {2}.", window.Handle.ToString(),
|
||||||
current_state.ToString(), value.ToString());
|
current_state.ToString(), value.ToString());
|
||||||
|
|
||||||
|
// When minimizing the window, call XIconifyWindow and bail out.
|
||||||
|
// For other states, we first need to restore the window, set the
|
||||||
|
// new state and reset the window border and bounds.
|
||||||
|
if (value != OpenTK.WindowState.Minimized)
|
||||||
|
{
|
||||||
|
// Some WMs cannot switch between specific states directly,
|
||||||
|
// Switch back to a regular window first.
|
||||||
|
if (WindowBorder == WindowBorder.Fixed)
|
||||||
|
{
|
||||||
|
ChangeWindowBorder(WindowBorder.Resizable);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetWindowState(current_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change to the desired WindowState.
|
||||||
|
// Note that OnWindowStateChanged is called inside
|
||||||
|
// ProcessEvents.
|
||||||
|
ChangeWindowState(value);
|
||||||
|
ProcessEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ResetWindowState(OpenTK.WindowState current_state)
|
||||||
|
{
|
||||||
|
if (current_state != OpenTK.WindowState.Normal)
|
||||||
|
{
|
||||||
using (new XLock(window.Display))
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
// Reset the current window state
|
switch (current_state)
|
||||||
if (current_state == OpenTK.WindowState.Minimized)
|
{
|
||||||
|
case OpenTK.WindowState.Minimized:
|
||||||
Functions.XMapWindow(window.Display, window.Handle);
|
Functions.XMapWindow(window.Display, window.Handle);
|
||||||
else if (current_state == OpenTK.WindowState.Fullscreen)
|
break;
|
||||||
Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_remove,
|
|
||||||
|
case OpenTK.WindowState.Fullscreen:
|
||||||
|
Functions.SendNetWMMessage(window,
|
||||||
|
_atom_net_wm_state,
|
||||||
|
_atom_remove,
|
||||||
_atom_net_wm_state_fullscreen,
|
_atom_net_wm_state_fullscreen,
|
||||||
IntPtr.Zero);
|
IntPtr.Zero);
|
||||||
else if (current_state == OpenTK.WindowState.Maximized)
|
break;
|
||||||
Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_toggle,
|
|
||||||
|
case OpenTK.WindowState.Maximized:
|
||||||
|
Functions.SendNetWMMessage(window,
|
||||||
|
_atom_net_wm_state,
|
||||||
|
_atom_toggle,
|
||||||
_atom_net_wm_state_maximized_horizontal,
|
_atom_net_wm_state_maximized_horizontal,
|
||||||
_atom_net_wm_state_maximized_vertical);
|
_atom_net_wm_state_maximized_vertical);
|
||||||
|
break;
|
||||||
Functions.XSync(window.Display, false);
|
|
||||||
}
|
}
|
||||||
// We can't resize the window if its border is fixed, so make it resizable first.
|
}
|
||||||
bool temporary_resizable = false;
|
}
|
||||||
WindowBorder previous_state = WindowBorder;
|
}
|
||||||
if (WindowBorder != WindowBorder.Resizable)
|
|
||||||
|
void ChangeWindowState(OpenTK.WindowState value)
|
||||||
{
|
{
|
||||||
temporary_resizable = true;
|
|
||||||
WindowBorder = WindowBorder.Resizable;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (new XLock(window.Display))
|
using (new XLock(window.Display))
|
||||||
{
|
{
|
||||||
switch (value)
|
switch (value)
|
||||||
{
|
{
|
||||||
case OpenTK.WindowState.Normal:
|
case OpenTK.WindowState.Normal:
|
||||||
Functions.XRaiseWindow(window.Display, window.Handle);
|
Functions.XRaiseWindow(window.Display, window.Handle);
|
||||||
|
ChangeWindowBorder(_previous_window_border,
|
||||||
|
_previous_window_size.Width, _previous_window_size.Height);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenTK.WindowState.Maximized:
|
case OpenTK.WindowState.Maximized:
|
||||||
|
@ -1364,54 +1343,64 @@ namespace OpenTK.Platform.X11
|
||||||
_atom_net_wm_state_maximized_horizontal,
|
_atom_net_wm_state_maximized_horizontal,
|
||||||
_atom_net_wm_state_maximized_vertical);
|
_atom_net_wm_state_maximized_vertical);
|
||||||
Functions.XRaiseWindow(window.Display, window.Handle);
|
Functions.XRaiseWindow(window.Display, window.Handle);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenTK.WindowState.Minimized:
|
case OpenTK.WindowState.Minimized:
|
||||||
// Todo: multiscreen support
|
|
||||||
Functions.XIconifyWindow(window.Display, window.Handle, window.Screen);
|
Functions.XIconifyWindow(window.Display, window.Handle, window.Screen);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenTK.WindowState.Fullscreen:
|
case OpenTK.WindowState.Fullscreen:
|
||||||
//_previous_window_border = this.WindowBorder;
|
|
||||||
//this.WindowBorder = WindowBorder.Hidden;
|
|
||||||
Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add,
|
Functions.SendNetWMMessage(window, _atom_net_wm_state, _atom_add,
|
||||||
_atom_net_wm_state_fullscreen, IntPtr.Zero);
|
_atom_net_wm_state_fullscreen, IntPtr.Zero);
|
||||||
Functions.XRaiseWindow(window.Display, window.Handle);
|
Functions.XRaiseWindow(window.Display, window.Handle);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temporary_resizable)
|
|
||||||
WindowBorder = previous_state;
|
|
||||||
|
|
||||||
ProcessEvents();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region WindowBorder
|
#region WindowBorder
|
||||||
|
|
||||||
public OpenTK.WindowBorder WindowBorder
|
public override OpenTK.WindowBorder WindowBorder
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (IsWindowBorderHidden)
|
if (IsWindowBorderHidden || WindowState == OpenTK.WindowState.Fullscreen)
|
||||||
return WindowBorder.Hidden;
|
return WindowBorder.Hidden;
|
||||||
|
else if (!IsWindowBorderResizable)
|
||||||
if (IsWindowBorderResizable)
|
|
||||||
return WindowBorder.Resizable;
|
|
||||||
else
|
|
||||||
return WindowBorder.Fixed;
|
return WindowBorder.Fixed;
|
||||||
|
else if (WindowState == OpenTK.WindowState.Maximized)
|
||||||
|
return _previous_window_border;
|
||||||
|
else
|
||||||
|
return WindowBorder.Resizable;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (WindowBorder == value)
|
if (WindowBorder == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// We cannot change the border of a fullscreen window.
|
||||||
|
// Record the new value and set it on the next WindowState
|
||||||
|
// change.
|
||||||
|
if (WindowState == OpenTK.WindowState.Fullscreen)
|
||||||
|
{
|
||||||
|
_previous_window_border = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeWindowBorder(value);
|
||||||
|
OnWindowBorderChanged(EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChangeWindowBorder(WindowBorder value)
|
||||||
|
{
|
||||||
|
ChangeWindowBorder(value, Width, Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChangeWindowBorder(WindowBorder value, int width, int height)
|
||||||
|
{
|
||||||
if (WindowBorder == WindowBorder.Hidden)
|
if (WindowBorder == WindowBorder.Hidden)
|
||||||
EnableWindowDecorations();
|
EnableWindowDecorations();
|
||||||
|
|
||||||
|
@ -1419,53 +1408,30 @@ namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
case WindowBorder.Fixed:
|
case WindowBorder.Fixed:
|
||||||
Debug.Print("Making WindowBorder fixed.");
|
Debug.Print("Making WindowBorder fixed.");
|
||||||
SetWindowMinMax((short)Width, (short)Height, (short)Width, (short)Height);
|
SetWindowMinMax((short)width, (short)height, (short)width, (short)height);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowBorder.Resizable:
|
case WindowBorder.Resizable:
|
||||||
Debug.Print("Making WindowBorder resizable.");
|
Debug.Print("Making WindowBorder resizable.");
|
||||||
SetWindowMinMax(_min_width, _min_height, -1, -1);
|
SetWindowMinMax(_min_width, _min_height, -1, -1);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WindowBorder.Hidden:
|
case WindowBorder.Hidden:
|
||||||
Debug.Print("Making WindowBorder hidden.");
|
Debug.Print("Making WindowBorder hidden.");
|
||||||
|
// Make the hidden border resizable, otherwise
|
||||||
|
// we won't be able to maximize the window or
|
||||||
|
// enter fullscreen mode.
|
||||||
|
SetWindowMinMax(_min_width, _min_height, -1, -1);
|
||||||
DisableWindowDecorations();
|
DisableWindowDecorations();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowBorderChanged(this, EventArgs.Empty);
|
ProcessEvents();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Events
|
|
||||||
|
|
||||||
public event EventHandler<EventArgs> Move = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Resize = delegate { };
|
|
||||||
public event EventHandler<System.ComponentModel.CancelEventArgs> Closing = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Closed = delegate { };
|
|
||||||
public event EventHandler<EventArgs> Disposed = delegate { };
|
|
||||||
public event EventHandler<EventArgs> IconChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> TitleChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> VisibleChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> FocusedChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> WindowBorderChanged = delegate { };
|
|
||||||
public event EventHandler<EventArgs> WindowStateChanged = delegate { };
|
|
||||||
public event EventHandler<KeyboardKeyEventArgs> KeyDown = delegate { };
|
|
||||||
public event EventHandler<KeyPressEventArgs> KeyPress = delegate { };
|
|
||||||
public event EventHandler<KeyboardKeyEventArgs> KeyUp = delegate { };
|
|
||||||
public event EventHandler<EventArgs> MouseEnter = delegate { };
|
|
||||||
public event EventHandler<EventArgs> MouseLeave = delegate { };
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Cursor
|
#region Cursor
|
||||||
|
|
||||||
public MouseCursor Cursor
|
public override MouseCursor Cursor
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1505,7 +1471,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region CursorVisible
|
#region CursorVisible
|
||||||
|
|
||||||
public bool CursorVisible
|
public override bool CursorVisible
|
||||||
{
|
{
|
||||||
get { return cursor_visible; }
|
get { return cursor_visible; }
|
||||||
set
|
set
|
||||||
|
@ -1535,24 +1501,12 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region --- INativeGLWindow Members ---
|
#region --- INativeGLWindow Members ---
|
||||||
|
|
||||||
#region public IInputDriver InputDriver
|
|
||||||
|
|
||||||
public IInputDriver InputDriver
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return driver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region public bool Exists
|
#region public bool Exists
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if a render window/context exists.
|
/// Returns true if a render window/context exists.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Exists
|
public override bool Exists
|
||||||
{
|
{
|
||||||
get { return exists; }
|
get { return exists; }
|
||||||
}
|
}
|
||||||
|
@ -1586,7 +1540,7 @@ namespace OpenTK.Platform.X11
|
||||||
/// TODO: Use atoms for this property.
|
/// TODO: Use atoms for this property.
|
||||||
/// Gets or sets the GameWindow title.
|
/// Gets or sets the GameWindow title.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Title
|
public override string Title
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1610,7 +1564,7 @@ namespace OpenTK.Platform.X11
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TitleChanged(this, EventArgs.Empty);
|
OnTitleChanged(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1618,7 +1572,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region public bool Visible
|
#region public bool Visible
|
||||||
|
|
||||||
public bool Visible
|
public override bool Visible
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -1647,14 +1601,14 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region public IWindowInfo WindowInfo
|
#region public IWindowInfo WindowInfo
|
||||||
|
|
||||||
public IWindowInfo WindowInfo
|
public override IWindowInfo WindowInfo
|
||||||
{
|
{
|
||||||
get { return window; }
|
get { return window; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public void Close() { Exit(); }
|
public override void Close() { Exit(); }
|
||||||
|
|
||||||
#region public void Exit()
|
#region public void Exit()
|
||||||
|
|
||||||
|
@ -1691,7 +1645,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region PointToClient
|
#region PointToClient
|
||||||
|
|
||||||
public Point PointToClient(Point point)
|
public override Point PointToClient(Point point)
|
||||||
{
|
{
|
||||||
int ox, oy;
|
int ox, oy;
|
||||||
IntPtr child;
|
IntPtr child;
|
||||||
|
@ -1711,7 +1665,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region PointToScreen
|
#region PointToScreen
|
||||||
|
|
||||||
public Point PointToScreen(Point point)
|
public override Point PointToScreen(Point point)
|
||||||
{
|
{
|
||||||
int ox, oy;
|
int ox, oy;
|
||||||
IntPtr child;
|
IntPtr child;
|
||||||
|
@ -1733,13 +1687,7 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
#region IDisposable Members
|
#region IDisposable Members
|
||||||
|
|
||||||
public void Dispose()
|
protected override void Dispose(bool manuallyCalled)
|
||||||
{
|
|
||||||
this.Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Dispose(bool manuallyCalled)
|
|
||||||
{
|
{
|
||||||
if (!disposed)
|
if (!disposed)
|
||||||
{
|
{
|
||||||
|
@ -1775,11 +1723,6 @@ namespace OpenTK.Platform.X11
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~X11GLNative()
|
|
||||||
{
|
|
||||||
this.Dispose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
#region --- License ---
|
|
||||||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
|
||||||
* See license.txt for license info
|
|
||||||
*/
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
#if !MINIMAL
|
|
||||||
using System.Drawing;
|
|
||||||
#endif
|
|
||||||
using System.Text;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using OpenTK.Input;
|
|
||||||
|
|
||||||
namespace OpenTK.Platform.X11
|
|
||||||
{
|
|
||||||
/// \internal
|
|
||||||
/// <summary>
|
|
||||||
/// Drives the InputDriver on X11.
|
|
||||||
/// This class supports OpenTK, and is not intended for users of OpenTK.
|
|
||||||
/// </summary>
|
|
||||||
internal sealed class X11Input : IInputDriver
|
|
||||||
{
|
|
||||||
KeyboardDevice keyboard = new KeyboardDevice();
|
|
||||||
MouseDevice mouse = new MouseDevice();
|
|
||||||
List<KeyboardDevice> dummy_keyboard_list = new List<KeyboardDevice>(1);
|
|
||||||
List<MouseDevice> dummy_mice_list = new List<MouseDevice>(1);
|
|
||||||
|
|
||||||
int firstKeyCode, lastKeyCode; // The smallest and largest KeyCode supported by the X server.
|
|
||||||
int keysyms_per_keycode; // The number of KeySyms for each KeyCode.
|
|
||||||
IntPtr[] keysyms;
|
|
||||||
|
|
||||||
//bool disposed;
|
|
||||||
|
|
||||||
#region --- Constructors ---
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructs a new X11Input driver. Creates a hidden InputOnly window, child to
|
|
||||||
/// the main application window, which selects input events and routes them to
|
|
||||||
/// the device specific drivers (Keyboard, Mouse, Hid).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="attach">The window which the InputDriver will attach itself on.</param>
|
|
||||||
public X11Input(IWindowInfo attach)
|
|
||||||
{
|
|
||||||
Debug.WriteLine("Initalizing X11 input driver.");
|
|
||||||
Debug.Indent();
|
|
||||||
|
|
||||||
if (attach == null)
|
|
||||||
throw new ArgumentException("A valid parent window must be defined, in order to create an X11Input driver.");
|
|
||||||
|
|
||||||
//window = new X11WindowInfo(attach);
|
|
||||||
X11WindowInfo window = (X11WindowInfo)attach;
|
|
||||||
|
|
||||||
// Init mouse
|
|
||||||
mouse.Description = "Default X11 mouse";
|
|
||||||
mouse.DeviceID = IntPtr.Zero;
|
|
||||||
mouse.NumberOfButtons = 5;
|
|
||||||
mouse.NumberOfWheels = 1;
|
|
||||||
dummy_mice_list.Add(mouse);
|
|
||||||
|
|
||||||
using (new XLock(window.Display))
|
|
||||||
{
|
|
||||||
// Init keyboard
|
|
||||||
API.DisplayKeycodes(window.Display, ref firstKeyCode, ref lastKeyCode);
|
|
||||||
Debug.Print("First keycode: {0}, last {1}", firstKeyCode, lastKeyCode);
|
|
||||||
|
|
||||||
IntPtr keysym_ptr = API.GetKeyboardMapping(window.Display, (byte)firstKeyCode,
|
|
||||||
lastKeyCode - firstKeyCode + 1, ref keysyms_per_keycode);
|
|
||||||
Debug.Print("{0} keysyms per keycode.", keysyms_per_keycode);
|
|
||||||
|
|
||||||
keysyms = new IntPtr[(lastKeyCode - firstKeyCode + 1) * keysyms_per_keycode];
|
|
||||||
Marshal.PtrToStructure(keysym_ptr, keysyms);
|
|
||||||
API.Free(keysym_ptr);
|
|
||||||
|
|
||||||
keyboard.Description = "Default X11 keyboard";
|
|
||||||
keyboard.NumberOfKeys = lastKeyCode - firstKeyCode + 1;
|
|
||||||
keyboard.DeviceID = IntPtr.Zero;
|
|
||||||
dummy_keyboard_list.Add(keyboard);
|
|
||||||
|
|
||||||
// Request that auto-repeat is only set on devices that support it physically.
|
|
||||||
// This typically means that it's turned off for keyboards (which is what we want).
|
|
||||||
// We prefer this method over XAutoRepeatOff/On, because the latter needs to
|
|
||||||
// be reset before the program exits.
|
|
||||||
bool supported;
|
|
||||||
Functions.XkbSetDetectableAutoRepeat(window.Display, true, out supported);
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.Unindent();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region TranslateKey
|
|
||||||
|
|
||||||
internal bool TranslateKey(ref XKeyEvent e, out Key key)
|
|
||||||
{
|
|
||||||
XKey keysym = (XKey)API.LookupKeysym(ref e, 0);
|
|
||||||
XKey keysym2 = (XKey)API.LookupKeysym(ref e, 1);
|
|
||||||
key = X11KeyMap.GetKey(keysym);
|
|
||||||
if (key == Key.Unknown)
|
|
||||||
{
|
|
||||||
key = X11KeyMap.GetKey(keysym2);
|
|
||||||
}
|
|
||||||
if (key == Key.Unknown)
|
|
||||||
{
|
|
||||||
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return key != Key.Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region internal void ProcessEvent(ref XEvent e)
|
|
||||||
|
|
||||||
internal void ProcessEvent(ref XEvent e)
|
|
||||||
{
|
|
||||||
switch (e.type)
|
|
||||||
{
|
|
||||||
case XEventName.ButtonPress:
|
|
||||||
if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true;
|
|
||||||
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = true;
|
|
||||||
else if (e.ButtonEvent.button == 3) mouse[OpenTK.Input.MouseButton.Right] = true;
|
|
||||||
else if (e.ButtonEvent.button == 4) mouse.Wheel++;
|
|
||||||
else if (e.ButtonEvent.button == 5) mouse.Wheel--;
|
|
||||||
else if (e.ButtonEvent.button == 6) mouse[OpenTK.Input.MouseButton.Button1] = true;
|
|
||||||
else if (e.ButtonEvent.button == 7) mouse[OpenTK.Input.MouseButton.Button2] = true;
|
|
||||||
else if (e.ButtonEvent.button == 8) mouse[OpenTK.Input.MouseButton.Button3] = true;
|
|
||||||
else if (e.ButtonEvent.button == 9) mouse[OpenTK.Input.MouseButton.Button4] = true;
|
|
||||||
else if (e.ButtonEvent.button == 10) mouse[OpenTK.Input.MouseButton.Button5] = true;
|
|
||||||
else if (e.ButtonEvent.button == 11) mouse[OpenTK.Input.MouseButton.Button6] = true;
|
|
||||||
else if (e.ButtonEvent.button == 12) mouse[OpenTK.Input.MouseButton.Button7] = true;
|
|
||||||
else if (e.ButtonEvent.button == 13) mouse[OpenTK.Input.MouseButton.Button8] = true;
|
|
||||||
else if (e.ButtonEvent.button == 14) mouse[OpenTK.Input.MouseButton.Button9] = true;
|
|
||||||
//if ((e.state & (int)X11.MouseMask.Button4Mask) != 0) m.Wheel++;
|
|
||||||
//if ((e.state & (int)X11.MouseMask.Button5Mask) != 0) m.Wheel--;
|
|
||||||
//Debug.Print("Button pressed: {0}", e.ButtonEvent.button);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XEventName.ButtonRelease:
|
|
||||||
if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = false;
|
|
||||||
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = false;
|
|
||||||
else if (e.ButtonEvent.button == 3) mouse[OpenTK.Input.MouseButton.Right] = false;
|
|
||||||
else if (e.ButtonEvent.button == 6) mouse[OpenTK.Input.MouseButton.Button1] = false;
|
|
||||||
else if (e.ButtonEvent.button == 7) mouse[OpenTK.Input.MouseButton.Button2] = false;
|
|
||||||
else if (e.ButtonEvent.button == 8) mouse[OpenTK.Input.MouseButton.Button3] = false;
|
|
||||||
else if (e.ButtonEvent.button == 9) mouse[OpenTK.Input.MouseButton.Button4] = false;
|
|
||||||
else if (e.ButtonEvent.button == 10) mouse[OpenTK.Input.MouseButton.Button5] = false;
|
|
||||||
else if (e.ButtonEvent.button == 11) mouse[OpenTK.Input.MouseButton.Button6] = false;
|
|
||||||
else if (e.ButtonEvent.button == 12) mouse[OpenTK.Input.MouseButton.Button7] = false;
|
|
||||||
else if (e.ButtonEvent.button == 13) mouse[OpenTK.Input.MouseButton.Button8] = false;
|
|
||||||
else if (e.ButtonEvent.button == 14) mouse[OpenTK.Input.MouseButton.Button9] = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XEventName.MotionNotify:
|
|
||||||
mouse.Position = new Point(e.MotionEvent.x, e.MotionEvent.y);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region --- IInputDriver Members ---
|
|
||||||
|
|
||||||
#region public IList<Keyboard> Keyboard
|
|
||||||
|
|
||||||
public IList<KeyboardDevice> Keyboard
|
|
||||||
{
|
|
||||||
get { return dummy_keyboard_list; }//return keyboardDriver.Keyboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region public IList<Mouse> Mouse
|
|
||||||
|
|
||||||
public IList<MouseDevice> Mouse
|
|
||||||
{
|
|
||||||
get { return (IList<MouseDevice>)dummy_mice_list; } //return mouseDriver.Mouse;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public IList<JoystickDevice> Joysticks
|
|
||||||
{
|
|
||||||
get { throw new NotImplementedException(); }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region public void Poll()
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Polls and updates state of all keyboard, mouse and joystick devices.
|
|
||||||
/// </summary>
|
|
||||||
public void Poll()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region --- IDisposable Members ---
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
//this.Dispose(true);
|
|
||||||
//GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
//private void Dispose(bool manual)
|
|
||||||
//{
|
|
||||||
// if (!disposed)
|
|
||||||
// {
|
|
||||||
// //disposing = true;
|
|
||||||
// if (pollingThread != null && pollingThread.IsAlive)
|
|
||||||
// pollingThread.Abort();
|
|
||||||
|
|
||||||
// if (manual)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// disposed = true;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//~X11Input()
|
|
||||||
//{
|
|
||||||
// this.Dispose(false);
|
|
||||||
//}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -370,5 +370,47 @@ namespace OpenTK.Platform.X11
|
||||||
return Key.Unknown;
|
return Key.Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static bool TranslateKey(ref XKeyEvent e, out Key key)
|
||||||
|
{
|
||||||
|
XKey keysym = (XKey)API.LookupKeysym(ref e, 0);
|
||||||
|
XKey keysym2 = (XKey)API.LookupKeysym(ref e, 1);
|
||||||
|
key = X11KeyMap.GetKey(keysym);
|
||||||
|
if (key == Key.Unknown)
|
||||||
|
{
|
||||||
|
key = X11KeyMap.GetKey(keysym2);
|
||||||
|
}
|
||||||
|
if (key == Key.Unknown)
|
||||||
|
{
|
||||||
|
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return key != Key.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static MouseButton TranslateButton(int button, out int wheelx, out int wheely)
|
||||||
|
{
|
||||||
|
wheelx = 0;
|
||||||
|
wheely = 0;
|
||||||
|
|
||||||
|
switch (button)
|
||||||
|
{
|
||||||
|
case 1: return MouseButton.Left;
|
||||||
|
case 2: return MouseButton.Middle;
|
||||||
|
case 3: return MouseButton.Right;
|
||||||
|
case 4: wheely = +1; return MouseButton.LastButton;
|
||||||
|
case 5: wheely = -1; return MouseButton.LastButton;
|
||||||
|
case 6: wheelx = +1; return MouseButton.LastButton;
|
||||||
|
case 7: wheelx = -1; return MouseButton.LastButton;
|
||||||
|
case 8: return MouseButton.Button1;
|
||||||
|
case 9: return MouseButton.Button2;
|
||||||
|
case 10: return MouseButton.Button3;
|
||||||
|
case 11: return MouseButton.Button4;
|
||||||
|
case 12: return MouseButton.Button5;
|
||||||
|
case 13: return MouseButton.Button6;
|
||||||
|
case 14: return MouseButton.Button7;
|
||||||
|
default: return MouseButton.LastButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,8 @@ namespace OpenTK.Platform.X11
|
||||||
List<MouseState> mice = new List<MouseState>();
|
List<MouseState> mice = new List<MouseState>();
|
||||||
Dictionary<int, int> rawids = new Dictionary<int, int>(); // maps raw ids to mouse ids
|
Dictionary<int, int> rawids = new Dictionary<int, int>(); // maps raw ids to mouse ids
|
||||||
internal readonly X11WindowInfo window;
|
internal readonly X11WindowInfo window;
|
||||||
static int XIOpCode;
|
internal static int XIOpCode { get; private set; }
|
||||||
|
static bool supported;
|
||||||
|
|
||||||
static readonly Functions.EventPredicate PredicateImpl = IsEventValid;
|
static readonly Functions.EventPredicate PredicateImpl = IsEventValid;
|
||||||
readonly IntPtr Predicate = Marshal.GetFunctionPointerForDelegate(PredicateImpl);
|
readonly IntPtr Predicate = Marshal.GetFunctionPointerForDelegate(PredicateImpl);
|
||||||
|
@ -204,8 +205,8 @@ namespace OpenTK.Platform.X11
|
||||||
case 1: state.EnableBit((int)MouseButton.Left); break;
|
case 1: state.EnableBit((int)MouseButton.Left); break;
|
||||||
case 2: state.EnableBit((int)MouseButton.Middle); break;
|
case 2: state.EnableBit((int)MouseButton.Middle); break;
|
||||||
case 3: state.EnableBit((int)MouseButton.Right); break;
|
case 3: state.EnableBit((int)MouseButton.Right); break;
|
||||||
case 4: state.WheelPrecise++; break;
|
case 4: state.SetScrollRelative(0, 1); break;
|
||||||
case 5: state.WheelPrecise--; break;
|
case 5: state.SetScrollRelative(0, -1); break;
|
||||||
case 6: state.EnableBit((int)MouseButton.Button1); break;
|
case 6: state.EnableBit((int)MouseButton.Button1); break;
|
||||||
case 7: state.EnableBit((int)MouseButton.Button2); break;
|
case 7: state.EnableBit((int)MouseButton.Button2); break;
|
||||||
case 8: state.EnableBit((int)MouseButton.Button3); break;
|
case 8: state.EnableBit((int)MouseButton.Button3); break;
|
||||||
|
|
Loading…
Reference in a new issue