mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-27 06:05:56 +00:00
8f159aef72
Added all Raw Input structs, functions and enums in Windows.API. WinRawKeyboard implements IKeyboard using Raw Input on Windows.
431 lines
12 KiB
C#
431 lines
12 KiB
C#
#region --- License ---
|
|
/* Copyright (c) 2007 Stefanos Apostolopoulos
|
|
* See license.txt for license info
|
|
*/
|
|
#endregion
|
|
|
|
#region --- Using directives ---
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Runtime.InteropServices;
|
|
using System.Windows.Forms;
|
|
using OpenTK.Input;
|
|
|
|
#endregion
|
|
|
|
namespace OpenTK.Platform.Windows
|
|
{
|
|
sealed class WinGLNative : NativeWindow, OpenTK.Platform.INativeWindow, IDisposable
|
|
{
|
|
private WinGLContext glContext;
|
|
private DisplayMode mode = new DisplayMode();
|
|
|
|
private bool disposed;
|
|
|
|
private WinRawKeyboard key;
|
|
|
|
#region --- Contructors ---
|
|
|
|
/// <summary>
|
|
/// Constructs a new WinGLNative window, using safe defaults for the DisplayMode.
|
|
/// </summary>
|
|
public WinGLNative()
|
|
{
|
|
mode = new DisplayMode();
|
|
mode.Width = 640;
|
|
mode.Height = 480;
|
|
|
|
this.CreateWindow(mode);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region private void CreateWindow()
|
|
|
|
private void CreateWindow(DisplayMode mode)
|
|
{
|
|
|
|
CreateParams cp = new CreateParams();
|
|
cp.ClassStyle =
|
|
(int)API.WindowClassStyle.OwnDC |
|
|
(int)API.WindowClassStyle.VRedraw |
|
|
(int)API.WindowClassStyle.HRedraw;
|
|
cp.Style =
|
|
(int)API.WindowStyle.Visible |
|
|
(int)API.WindowStyle.ClipChildren |
|
|
(int)API.WindowStyle.ClipSiblings |
|
|
(int)API.WindowStyle.OverlappedWindow;
|
|
cp.Width = mode.Width;
|
|
cp.Height = mode.Height;
|
|
cp.Caption = "OpenTK Game Window";
|
|
base.CreateHandle(cp);
|
|
|
|
glContext = new WinGLContext(
|
|
this.Handle,
|
|
new DisplayMode(
|
|
width, height,
|
|
new ColorDepth(32),
|
|
16, 0, 0, 2,
|
|
fullscreen,
|
|
false,
|
|
false,
|
|
0.0f
|
|
)
|
|
);
|
|
|
|
if (Environment.OSVersion.Version.Major > 5 ||
|
|
(Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1))
|
|
key = new WinRawKeyboard(this.Handle); // WinXP and higher support raw input.
|
|
else
|
|
throw new PlatformNotSupportedException("Input is not implemented for platforms prior to Windows XP, yet.");
|
|
}
|
|
|
|
/*
|
|
private void CreateWindow()
|
|
{
|
|
WinApi.WindowClass wc = new WinApi.WindowClass();
|
|
wc.style =
|
|
WinApi.WindowClassStyle.HRedraw |
|
|
WinApi.WindowClassStyle.VRedraw |
|
|
WinApi.WindowClassStyle.OwnDC;
|
|
wc.WindowProcedure = new WinApi.WindowProcedureEventHandler(WndProc);
|
|
wc.Instance = instance;
|
|
//wc.ClassName = Marshal.StringToHGlobalAuto(className);
|
|
wc.ClassName = className;
|
|
|
|
classAtom = WinApi.RegisterClass(wc);
|
|
|
|
if (classAtom == 0)
|
|
{
|
|
throw new Exception("Could not register class, error: " + Marshal.GetLastWin32Error());
|
|
}
|
|
|
|
// Change for fullscreen!
|
|
handle = WinApi.CreateWindowEx(
|
|
WinApi.ExtendedWindowStyle.ApplicationWindow |
|
|
WinApi.ExtendedWindowStyle.OverlappedWindow |
|
|
WinApi.ExtendedWindowStyle.Topmost,
|
|
className,
|
|
//Marshal.StringToHGlobalAuto("OpenTK Game Window"),
|
|
"OpenTK Game Window",
|
|
WinApi.WindowStyle.OverlappedWindow |
|
|
WinApi.WindowStyle.ClipChildren |
|
|
WinApi.WindowStyle.ClipSiblings,
|
|
0, 0,
|
|
640, 480,
|
|
IntPtr.Zero,
|
|
IntPtr.Zero,
|
|
instance,
|
|
IntPtr.Zero
|
|
);
|
|
|
|
if (handle == IntPtr.Zero)
|
|
{
|
|
throw new Exception("Could not create window, error: " + Marshal.GetLastWin32Error());
|
|
}
|
|
}
|
|
*/
|
|
#endregion
|
|
|
|
#region protected override void WndProc(ref Message m)
|
|
|
|
/// <summary>
|
|
/// For use in WndProc only.
|
|
/// </summary>
|
|
private int width, height;
|
|
|
|
/// <summary>
|
|
/// Processes incoming WM_* messages.
|
|
/// </summary>
|
|
/// <param name="m">Reference to the incoming Windows Message.</param>
|
|
protected override void WndProc(ref Message m)
|
|
{
|
|
switch (m.Msg)
|
|
{
|
|
case API.Constants.WM_WINDOWPOSCHANGED:
|
|
// Get window size
|
|
width = Marshal.ReadInt32(m.LParam, (int)Marshal.OffsetOf(typeof(API.WindowPosition), "cx"));
|
|
height = Marshal.ReadInt32(m.LParam, (int)Marshal.OffsetOf(typeof(API.WindowPosition), "cy"));
|
|
//if (resizeEventArgs.Width != width || resizeEventArgs.Height != height)
|
|
if (mode.Width != width || mode.Height != height)
|
|
{
|
|
// If the size has changed, raise the ResizeEvent.
|
|
resizeEventArgs.Width = width;
|
|
resizeEventArgs.Height = height;
|
|
this.OnResize(resizeEventArgs);
|
|
// The message was processed.
|
|
return;
|
|
}
|
|
// If the message was not a resize notification, send it to the default WndProc.
|
|
break;
|
|
|
|
case API.Constants.WM_CREATE:
|
|
// Set the window width and height:
|
|
mode.Width = Marshal.ReadInt32(m.LParam, (int)Marshal.OffsetOf(typeof(API.CreateStruct), "cx"));
|
|
mode.Height = Marshal.ReadInt32(m.LParam, (int)Marshal.OffsetOf(typeof(API.CreateStruct), "cy"));
|
|
|
|
// Raise the Create event
|
|
this.OnCreate(EventArgs.Empty);
|
|
|
|
// Raise the resize event:
|
|
//resizeEventArgs.Width = width;
|
|
//resizeEventArgs.Height = height;
|
|
//this.OnResize(resizeEventArgs);
|
|
return;
|
|
|
|
case API.Constants.WM_KEYDOWN: // Legacy input events
|
|
case API.Constants.WM_KEYUP:
|
|
break;
|
|
|
|
case API.Constants.WM_INPUT: // Raw input
|
|
API.RawInput rin = WinRawInput.ProcessEvent(ref msg);
|
|
if (rin.Header.Type == API.RawInputDeviceType.KEYBOARD)
|
|
{
|
|
if (this.key.ProcessEvent(rin))
|
|
return;
|
|
else
|
|
break;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case API.Constants.WM_CLOSE:
|
|
API.PostQuitMessage(0);
|
|
return;
|
|
|
|
case API.Constants.WM_QUIT:
|
|
quit = true;
|
|
break;
|
|
}
|
|
|
|
base.WndProc(ref m);
|
|
}
|
|
|
|
private bool ProcessKey(ref Message m)
|
|
{
|
|
switch ((int)m.WParam)
|
|
{
|
|
case API.Constants.VK_ESCAPE:
|
|
//= (m.Msg == API.Constants.WM_KEYDOWN) ? true : false;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region --- INativeWindow Members ---
|
|
|
|
#region public void ProcessEvents()
|
|
|
|
private System.Windows.Forms.Message msg;
|
|
public void ProcessEvents()
|
|
{
|
|
while (API.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0))
|
|
{
|
|
API.GetMessage(out msg, IntPtr.Zero, 0, 0);
|
|
WndProc(ref msg);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public event CreateEvent Create;
|
|
|
|
public event CreateEvent Create;
|
|
|
|
private void OnCreate(EventArgs e)
|
|
{
|
|
if (this.Create != null)
|
|
{
|
|
this.Create(this, e);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public IKeyboard Key
|
|
|
|
public IKeyboard Key
|
|
{
|
|
get { return this.key; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public bool Quit
|
|
|
|
private bool quit;
|
|
public bool Quit
|
|
{
|
|
get { return quit; }
|
|
set
|
|
{
|
|
if (value)
|
|
{
|
|
API.PostQuitMessage(0);
|
|
//quit = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public IGLContext Context
|
|
|
|
public IGLContext Context
|
|
{
|
|
get { return glContext; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public bool Fullscreen
|
|
|
|
bool fullscreen;
|
|
public bool Fullscreen
|
|
{
|
|
get
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
set
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public bool IsIdle
|
|
|
|
public bool IsIdle
|
|
{
|
|
get
|
|
{
|
|
return !API.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
#region --- IDisposable Members ---
|
|
|
|
public void Dispose()
|
|
{
|
|
this.Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
|
|
}
|
|
|
|
private void Dispose(bool calledManually)
|
|
{
|
|
if (!disposed)
|
|
{
|
|
// Clean unmanaged resources here:
|
|
|
|
if (calledManually)
|
|
{
|
|
// Safe to clean managed resources
|
|
glContext.Dispose();
|
|
base.DestroyHandle();
|
|
}
|
|
disposed = true;
|
|
}
|
|
}
|
|
|
|
~WinGLNative()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region --- IResizable Members ---
|
|
|
|
#region public int Width
|
|
|
|
public int Width
|
|
{
|
|
get
|
|
{
|
|
return mode.Width;
|
|
}
|
|
set
|
|
{
|
|
throw new NotImplementedException();
|
|
//WinApi.PostMessage(
|
|
// this.Handle,
|
|
// WinApi.Constants.WM_WINDOWPOSCHANGING,
|
|
|
|
//mode.Width = value;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public int Height
|
|
|
|
public int Height
|
|
{
|
|
get
|
|
{
|
|
return mode.Height;
|
|
}
|
|
set
|
|
{
|
|
throw new NotImplementedException();
|
|
//WinApi.PostMessage(
|
|
// this.Handle,
|
|
// WinApi.Constants.WM_WINDOWPOSCHANGING,
|
|
|
|
//mode.Height = value;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region public event ResizeEvent Resize
|
|
public event ResizeEvent Resize;
|
|
private ResizeEventArgs resizeEventArgs = new ResizeEventArgs();
|
|
public void OnResize(ResizeEventArgs e)
|
|
{
|
|
mode.Width = e.Width;
|
|
mode.Height = e.Height;
|
|
if (this.Resize != null)
|
|
this.Resize(this, e);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
}
|
|
|
|
#region class WindowHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
|
|
|
/*
|
|
class WindowHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
|
{
|
|
protected override bool ReleaseHandle()
|
|
{
|
|
throw new Exception("The method or operation is not implemented.");
|
|
}
|
|
|
|
public override bool IsInvalid
|
|
{
|
|
get
|
|
{
|
|
return base.IsInvalid;
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
|
|
#endregion
|
|
}
|