mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-11 11:15:28 +00:00
Fixed line endings
This commit is contained in:
parent
fb86334835
commit
459313dca8
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,15 +1,15 @@
|
|||
<configuration>
|
||||
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
|
||||
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
|
||||
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
|
||||
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
|
||||
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
|
||||
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
|
||||
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
|
||||
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
||||
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
||||
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
|
||||
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
|
||||
</configuration>
|
||||
<configuration>
|
||||
<dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
|
||||
<dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
|
||||
<dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
|
||||
<dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
|
||||
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
|
||||
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
|
||||
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
|
||||
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
|
||||
<dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
||||
<dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
|
||||
<dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
|
||||
<dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
|
||||
</configuration>
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
abstract class DisplayDeviceBase : IDisplayDeviceDriver
|
||||
{
|
||||
protected readonly List<DisplayDevice> AvailableDevices = new List<DisplayDevice>();
|
||||
protected DisplayDevice Primary;
|
||||
|
||||
public abstract bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution);
|
||||
public abstract bool TryRestoreResolution(DisplayDevice device);
|
||||
|
||||
// Gets the DisplayDevice that corresponds to the specified index.
|
||||
public virtual DisplayDevice GetDisplay(DisplayIndex index)
|
||||
{
|
||||
if (index == DisplayIndex.Primary)
|
||||
return Primary;
|
||||
else if ((int)index >= 0 && (int)index < AvailableDevices.Count)
|
||||
return AvailableDevices[(int)index];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
abstract class DisplayDeviceBase : IDisplayDeviceDriver
|
||||
{
|
||||
protected readonly List<DisplayDevice> AvailableDevices = new List<DisplayDevice>();
|
||||
protected DisplayDevice Primary;
|
||||
|
||||
public abstract bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution);
|
||||
public abstract bool TryRestoreResolution(DisplayDevice device);
|
||||
|
||||
// Gets the DisplayDevice that corresponds to the specified index.
|
||||
public virtual DisplayDevice GetDisplay(DisplayIndex index)
|
||||
{
|
||||
if (index == DisplayIndex.Primary)
|
||||
return Primary;
|
||||
else if ((int)index >= 0 && (int)index < AvailableDevices.Count)
|
||||
return AvailableDevices[(int)index];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -943,30 +943,30 @@ namespace OpenTK.Platform.Windows
|
|||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern HMONITOR MonitorFromWindow(HWND hwnd, MonitorFrom dwFlags);
|
||||
|
||||
#endregion
|
||||
|
||||
#region SetProcessDPIAware
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current process as dots per inch (dpi) aware.
|
||||
/// Note: SetProcessDPIAware is subject to a possible race condition
|
||||
/// if a DLL caches dpi settings during initialization.
|
||||
/// For this reason, it is recommended that dpi-aware be set through
|
||||
/// the application (.exe) manifest rather than by calling SetProcessDPIAware.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is true.
|
||||
/// Otherwise, the return value is false.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// DLLs should accept the dpi setting of the host process
|
||||
/// rather than call SetProcessDPIAware themselves.
|
||||
/// To be set properly, dpiAware should be specified as part
|
||||
/// of the application (.exe) manifest.
|
||||
/// </remarks>
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern BOOL SetProcessDPIAware();
|
||||
|
||||
#endregion
|
||||
|
||||
#region SetProcessDPIAware
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current process as dots per inch (dpi) aware.
|
||||
/// Note: SetProcessDPIAware is subject to a possible race condition
|
||||
/// if a DLL caches dpi settings during initialization.
|
||||
/// For this reason, it is recommended that dpi-aware be set through
|
||||
/// the application (.exe) manifest rather than by calling SetProcessDPIAware.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is true.
|
||||
/// Otherwise, the return value is false.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// DLLs should accept the dpi setting of the host process
|
||||
/// rather than call SetProcessDPIAware themselves.
|
||||
/// To be set properly, dpiAware should be specified as part
|
||||
/// of the application (.exe) manifest.
|
||||
/// </remarks>
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern BOOL SetProcessDPIAware();
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
|
@ -39,17 +39,17 @@ namespace OpenTK.Platform.Windows
|
|||
{
|
||||
bool disposed;
|
||||
readonly object SyncRoot = new object();
|
||||
IInputDriver2 inputDriver;
|
||||
|
||||
public WinFactory()
|
||||
{
|
||||
if (System.Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
// Enable high-dpi support
|
||||
// Only available on Windows Vista and higher
|
||||
bool result = Functions.SetProcessDPIAware();
|
||||
Debug.Print("SetProcessDPIAware() returned {0}", result);
|
||||
}
|
||||
IInputDriver2 inputDriver;
|
||||
|
||||
public WinFactory()
|
||||
{
|
||||
if (System.Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
// Enable high-dpi support
|
||||
// Only available on Windows Vista and higher
|
||||
bool result = Functions.SetProcessDPIAware();
|
||||
Debug.Print("SetProcessDPIAware() returned {0}", result);
|
||||
}
|
||||
}
|
||||
|
||||
#region IPlatformFactory Members
|
||||
|
|
|
@ -1,203 +1,203 @@
|
|||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
abstract class WinInputBase : IInputDriver2
|
||||
{
|
||||
#region Fields
|
||||
|
||||
readonly WindowProcedure WndProc;
|
||||
readonly Thread InputThread;
|
||||
readonly AutoResetEvent InputReady = new AutoResetEvent(false);
|
||||
|
||||
IntPtr OldWndProc;
|
||||
INativeWindow native;
|
||||
|
||||
protected INativeWindow Native { get { return native; } private set { native = value; } }
|
||||
protected WinWindowInfo Parent { get { return (WinWindowInfo)Native.WindowInfo; } }
|
||||
|
||||
static readonly IntPtr Unhandled = new IntPtr(-1);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public WinInputBase()
|
||||
{
|
||||
WndProc = WindowProcedure;
|
||||
|
||||
InputThread = new Thread(ProcessEvents);
|
||||
InputThread.IsBackground = true;
|
||||
InputThread.Start();
|
||||
|
||||
InputReady.WaitOne();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Members
|
||||
|
||||
#region ConstructMessageWindow
|
||||
|
||||
INativeWindow ConstructMessageWindow()
|
||||
{
|
||||
Debug.WriteLine("Initializing input driver.");
|
||||
Debug.Indent();
|
||||
|
||||
// Create a new message-only window to retrieve WM_INPUT messages.
|
||||
INativeWindow native = new NativeWindow();
|
||||
native.ProcessEvents();
|
||||
WinWindowInfo parent = native.WindowInfo as WinWindowInfo;
|
||||
Functions.SetParent(parent.Handle, Constants.MESSAGE_ONLY);
|
||||
native.ProcessEvents();
|
||||
|
||||
Debug.Unindent();
|
||||
return native;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ProcessEvents
|
||||
|
||||
void ProcessEvents()
|
||||
{
|
||||
Native = ConstructMessageWindow();
|
||||
CreateDrivers();
|
||||
|
||||
// Subclass the window to retrieve the events we are interested in.
|
||||
OldWndProc = Functions.SetWindowLong(Parent.Handle, WndProc);
|
||||
Debug.Print("Input window attached to {0}", Parent);
|
||||
|
||||
InputReady.Set();
|
||||
|
||||
MSG msg = new MSG();
|
||||
while (Native.Exists)
|
||||
{
|
||||
int ret = Functions.GetMessage(ref msg, Parent.Handle, 0, 0);
|
||||
if (ret == -1)
|
||||
{
|
||||
throw new PlatformException(String.Format(
|
||||
"An error happened while processing the message queue. Windows error: {0}",
|
||||
Marshal.GetLastWin32Error()));
|
||||
}
|
||||
|
||||
Functions.TranslateMessage(ref msg);
|
||||
Functions.DispatchMessage(ref msg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WndProcHandler
|
||||
|
||||
IntPtr WndProcHandler(
|
||||
IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
IntPtr ret = WindowProcedure(handle, message, wParam, lParam);
|
||||
if (ret == Unhandled)
|
||||
return Functions.CallWindowProc(OldWndProc, handle, message, wParam, lParam);
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Members
|
||||
|
||||
#region WindowProcedure
|
||||
|
||||
protected virtual IntPtr WindowProcedure(
|
||||
IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
return Unhandled;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CreateDrivers
|
||||
|
||||
// Note: this method is called through the input thread.
|
||||
protected abstract void CreateDrivers();
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IInputDriver2 Members
|
||||
|
||||
public abstract IMouseDriver2 MouseDriver { get; }
|
||||
public abstract IKeyboardDriver2 KeyboardDriver { get; }
|
||||
public abstract IGamePadDriver GamePadDriver { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
protected bool Disposed;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool manual)
|
||||
{
|
||||
if (!Disposed)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
if (Native != null)
|
||||
{
|
||||
Native.Close();
|
||||
Native.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
~WinInputBase()
|
||||
{
|
||||
Debug.Print("[Warning] Resource leaked: {0}.", this);
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
abstract class WinInputBase : IInputDriver2
|
||||
{
|
||||
#region Fields
|
||||
|
||||
readonly WindowProcedure WndProc;
|
||||
readonly Thread InputThread;
|
||||
readonly AutoResetEvent InputReady = new AutoResetEvent(false);
|
||||
|
||||
IntPtr OldWndProc;
|
||||
INativeWindow native;
|
||||
|
||||
protected INativeWindow Native { get { return native; } private set { native = value; } }
|
||||
protected WinWindowInfo Parent { get { return (WinWindowInfo)Native.WindowInfo; } }
|
||||
|
||||
static readonly IntPtr Unhandled = new IntPtr(-1);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public WinInputBase()
|
||||
{
|
||||
WndProc = WindowProcedure;
|
||||
|
||||
InputThread = new Thread(ProcessEvents);
|
||||
InputThread.IsBackground = true;
|
||||
InputThread.Start();
|
||||
|
||||
InputReady.WaitOne();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Members
|
||||
|
||||
#region ConstructMessageWindow
|
||||
|
||||
INativeWindow ConstructMessageWindow()
|
||||
{
|
||||
Debug.WriteLine("Initializing input driver.");
|
||||
Debug.Indent();
|
||||
|
||||
// Create a new message-only window to retrieve WM_INPUT messages.
|
||||
INativeWindow native = new NativeWindow();
|
||||
native.ProcessEvents();
|
||||
WinWindowInfo parent = native.WindowInfo as WinWindowInfo;
|
||||
Functions.SetParent(parent.Handle, Constants.MESSAGE_ONLY);
|
||||
native.ProcessEvents();
|
||||
|
||||
Debug.Unindent();
|
||||
return native;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ProcessEvents
|
||||
|
||||
void ProcessEvents()
|
||||
{
|
||||
Native = ConstructMessageWindow();
|
||||
CreateDrivers();
|
||||
|
||||
// Subclass the window to retrieve the events we are interested in.
|
||||
OldWndProc = Functions.SetWindowLong(Parent.Handle, WndProc);
|
||||
Debug.Print("Input window attached to {0}", Parent);
|
||||
|
||||
InputReady.Set();
|
||||
|
||||
MSG msg = new MSG();
|
||||
while (Native.Exists)
|
||||
{
|
||||
int ret = Functions.GetMessage(ref msg, Parent.Handle, 0, 0);
|
||||
if (ret == -1)
|
||||
{
|
||||
throw new PlatformException(String.Format(
|
||||
"An error happened while processing the message queue. Windows error: {0}",
|
||||
Marshal.GetLastWin32Error()));
|
||||
}
|
||||
|
||||
Functions.TranslateMessage(ref msg);
|
||||
Functions.DispatchMessage(ref msg);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WndProcHandler
|
||||
|
||||
IntPtr WndProcHandler(
|
||||
IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
IntPtr ret = WindowProcedure(handle, message, wParam, lParam);
|
||||
if (ret == Unhandled)
|
||||
return Functions.CallWindowProc(OldWndProc, handle, message, wParam, lParam);
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Members
|
||||
|
||||
#region WindowProcedure
|
||||
|
||||
protected virtual IntPtr WindowProcedure(
|
||||
IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||
{
|
||||
return Unhandled;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region CreateDrivers
|
||||
|
||||
// Note: this method is called through the input thread.
|
||||
protected abstract void CreateDrivers();
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IInputDriver2 Members
|
||||
|
||||
public abstract IMouseDriver2 MouseDriver { get; }
|
||||
public abstract IKeyboardDriver2 KeyboardDriver { get; }
|
||||
public abstract IGamePadDriver GamePadDriver { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
protected bool Disposed;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool manual)
|
||||
{
|
||||
if (!Disposed)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
if (Native != null)
|
||||
{
|
||||
Native.Close();
|
||||
Native.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
~WinInputBase()
|
||||
{
|
||||
Debug.Print("[Warning] Resource leaked: {0}.", this);
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,125 +1,125 @@
|
|||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
// Standard keyboard driver that relies on xlib input events.
|
||||
// Only one keyboard supported.
|
||||
sealed class X11Keyboard : IKeyboardDriver2
|
||||
{
|
||||
readonly static X11KeyMap keymap = new X11KeyMap();
|
||||
readonly static string name = "Core X11 keyboard";
|
||||
readonly byte[] keys = new byte[32];
|
||||
readonly int KeysymsPerKeycode;
|
||||
KeyboardState state = new KeyboardState();
|
||||
|
||||
public X11Keyboard()
|
||||
{
|
||||
Debug.WriteLine("Using X11Keyboard.");
|
||||
state.IsConnected = true;
|
||||
|
||||
IntPtr display = API.DefaultDisplay;
|
||||
using (new XLock(display))
|
||||
{
|
||||
// Find the number of keysyms per keycode.
|
||||
int first = 0, last = 0;
|
||||
API.DisplayKeycodes(display, ref first, ref last);
|
||||
IntPtr keysym_ptr = API.GetKeyboardMapping(display, (byte)first, last - first + 1,
|
||||
ref KeysymsPerKeycode);
|
||||
Functions.XFree(keysym_ptr);
|
||||
|
||||
try
|
||||
{
|
||||
// Request that auto-repeat is only set on devices that support it physically.
|
||||
// This typically means that it's turned off for keyboards 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(display, true, out supported);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
ProcessEvents();
|
||||
return state;
|
||||
}
|
||||
|
||||
public KeyboardState GetState(int index)
|
||||
{
|
||||
// X11Keyboard supports a single keyboard only
|
||||
ProcessEvents();
|
||||
if (index == 0)
|
||||
return state;
|
||||
else
|
||||
return new KeyboardState();
|
||||
}
|
||||
|
||||
public string GetDeviceName(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
return name;
|
||||
else
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
void ProcessEvents()
|
||||
{
|
||||
IntPtr display = API.DefaultDisplay;
|
||||
using (new XLock(display))
|
||||
{
|
||||
Functions.XQueryKeymap(display, keys);
|
||||
for (int keycode = 8; keycode < 256; keycode++)
|
||||
{
|
||||
bool pressed = (keys[keycode >> 3] >> (keycode & 0x07) & 0x01) != 0;
|
||||
Key key;
|
||||
|
||||
for (int mod = 0; mod < KeysymsPerKeycode; mod++)
|
||||
{
|
||||
IntPtr keysym = Functions.XKeycodeToKeysym(display, (byte)keycode, mod);
|
||||
if (keysym != IntPtr.Zero && keymap.TryGetValue((XKey)keysym, out key))
|
||||
{
|
||||
if (pressed)
|
||||
state.EnableBit((int)key);
|
||||
else
|
||||
state.DisableBit((int)key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
// Standard keyboard driver that relies on xlib input events.
|
||||
// Only one keyboard supported.
|
||||
sealed class X11Keyboard : IKeyboardDriver2
|
||||
{
|
||||
readonly static X11KeyMap keymap = new X11KeyMap();
|
||||
readonly static string name = "Core X11 keyboard";
|
||||
readonly byte[] keys = new byte[32];
|
||||
readonly int KeysymsPerKeycode;
|
||||
KeyboardState state = new KeyboardState();
|
||||
|
||||
public X11Keyboard()
|
||||
{
|
||||
Debug.WriteLine("Using X11Keyboard.");
|
||||
state.IsConnected = true;
|
||||
|
||||
IntPtr display = API.DefaultDisplay;
|
||||
using (new XLock(display))
|
||||
{
|
||||
// Find the number of keysyms per keycode.
|
||||
int first = 0, last = 0;
|
||||
API.DisplayKeycodes(display, ref first, ref last);
|
||||
IntPtr keysym_ptr = API.GetKeyboardMapping(display, (byte)first, last - first + 1,
|
||||
ref KeysymsPerKeycode);
|
||||
Functions.XFree(keysym_ptr);
|
||||
|
||||
try
|
||||
{
|
||||
// Request that auto-repeat is only set on devices that support it physically.
|
||||
// This typically means that it's turned off for keyboards 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(display, true, out supported);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
ProcessEvents();
|
||||
return state;
|
||||
}
|
||||
|
||||
public KeyboardState GetState(int index)
|
||||
{
|
||||
// X11Keyboard supports a single keyboard only
|
||||
ProcessEvents();
|
||||
if (index == 0)
|
||||
return state;
|
||||
else
|
||||
return new KeyboardState();
|
||||
}
|
||||
|
||||
public string GetDeviceName(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
return name;
|
||||
else
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
void ProcessEvents()
|
||||
{
|
||||
IntPtr display = API.DefaultDisplay;
|
||||
using (new XLock(display))
|
||||
{
|
||||
Functions.XQueryKeymap(display, keys);
|
||||
for (int keycode = 8; keycode < 256; keycode++)
|
||||
{
|
||||
bool pressed = (keys[keycode >> 3] >> (keycode & 0x07) & 0x01) != 0;
|
||||
Key key;
|
||||
|
||||
for (int mod = 0; mod < KeysymsPerKeycode; mod++)
|
||||
{
|
||||
IntPtr keysym = Functions.XKeycodeToKeysym(display, (byte)keycode, mod);
|
||||
if (keysym != IntPtr.Zero && keymap.TryGetValue((XKey)keysym, out key))
|
||||
{
|
||||
if (pressed)
|
||||
state.EnableBit((int)key);
|
||||
else
|
||||
state.DisableBit((int)key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,152 +1,152 @@
|
|||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
// Note: we cannot create a background window to retrieve events,
|
||||
// because X11 doesn't deliver core pointer events to background
|
||||
// windows (unless we grab, which will break *everything*).
|
||||
// The only solution is to poll.
|
||||
// Note 2: this driver only supports absolute positions. Relative motion
|
||||
// is faked through SetPosition. This is called automatically when
|
||||
// NativeWindow.CursorVisible = false, otherwise it must be called
|
||||
// by the user.
|
||||
// Note 3: this driver cannot drive the mouse wheel reliably.
|
||||
// See comments in ProcessEvents() for more information.
|
||||
// (If someone knows of a solution, please tell!)
|
||||
sealed class X11Mouse : IMouseDriver2
|
||||
{
|
||||
readonly IntPtr display;
|
||||
readonly IntPtr root_window;
|
||||
MouseState mouse = new MouseState();
|
||||
|
||||
// When the mouse warps, "detach" the current location
|
||||
// from the pointer.
|
||||
bool mouse_detached;
|
||||
int mouse_detached_x, mouse_detached_y;
|
||||
|
||||
public X11Mouse()
|
||||
{
|
||||
Debug.WriteLine("Using X11Mouse.");
|
||||
mouse.IsConnected = true;
|
||||
display = API.DefaultDisplay;
|
||||
root_window = Functions.XRootWindow(display, Functions.XDefaultScreen(display));
|
||||
}
|
||||
|
||||
public MouseState GetState()
|
||||
{
|
||||
ProcessEvents();
|
||||
return mouse;
|
||||
}
|
||||
|
||||
public MouseState GetState(int index)
|
||||
{
|
||||
ProcessEvents();
|
||||
// X11Mouse supports only one device
|
||||
if (index == 0)
|
||||
return mouse;
|
||||
else
|
||||
return new MouseState();
|
||||
}
|
||||
|
||||
public void SetPosition(double x, double y)
|
||||
{
|
||||
// Update the current location, otherwise the pointer
|
||||
// may become locked (for instance, if we call
|
||||
// SetPosition too often, like X11GLNative does).
|
||||
ProcessEvents();
|
||||
|
||||
using (new XLock(display))
|
||||
{
|
||||
// Mark the expected warp-event so it can be ignored.
|
||||
mouse_detached = true;
|
||||
mouse_detached_x = (int)x;
|
||||
mouse_detached_y = (int)y;
|
||||
|
||||
Functions.XWarpPointer(display,
|
||||
IntPtr.Zero, root_window, 0, 0, 0, 0, (int)x, (int)y);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteBit(MouseButton offset, int enabled)
|
||||
{
|
||||
if (enabled != 0)
|
||||
mouse.EnableBit((int)offset);
|
||||
else
|
||||
mouse.DisableBit((int)offset);
|
||||
}
|
||||
|
||||
void ProcessEvents()
|
||||
{
|
||||
IntPtr root, child;
|
||||
int root_x, root_y, win_x, win_y;
|
||||
int buttons;
|
||||
|
||||
using (new XLock(display))
|
||||
{
|
||||
IntPtr window = root_window;
|
||||
Functions.XQueryPointer(display, window, out root, out child,
|
||||
out root_x, out root_y, out win_x, out win_y, out buttons);
|
||||
|
||||
if (!mouse_detached)
|
||||
{
|
||||
mouse.X = root_x;
|
||||
mouse.Y = root_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse.X += (int)root_x - mouse_detached_x;
|
||||
mouse.Y += (int)root_y - mouse_detached_y;
|
||||
mouse_detached_x = root_x;
|
||||
mouse_detached_y = root_y;
|
||||
}
|
||||
WriteBit(MouseButton.Left, buttons & (int)MouseMask.Button1Mask);
|
||||
WriteBit(MouseButton.Middle, buttons & (int)MouseMask.Button2Mask);
|
||||
WriteBit(MouseButton.Right, buttons & (int)MouseMask.Button3Mask);
|
||||
// Note: this will never work right, wheel events have a duration of 0
|
||||
// (yes, zero). They are impposible to catch via polling.
|
||||
// After spending a week on this, I simply don't care anymore.
|
||||
// If someone can fix it, please do.
|
||||
// Note 2: I have tried passively grabbing those buttons - no go (BadAccess).
|
||||
// Maybe I am doing something wrong with the grab.
|
||||
//if ((buttons & (int)MouseMask.Button4Mask) != 0)
|
||||
// mouse.WheelPrecise++;
|
||||
//if ((buttons & (int)MouseMask.Button5Mask) != 0)
|
||||
// mouse.WheelPrecise--;
|
||||
WriteBit(MouseButton.Button1, buttons & (int)MouseMask.Button6Mask);
|
||||
WriteBit(MouseButton.Button2, buttons & (int)MouseMask.Button7Mask);
|
||||
WriteBit(MouseButton.Button3, buttons & (int)MouseMask.Button8Mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
// Note: we cannot create a background window to retrieve events,
|
||||
// because X11 doesn't deliver core pointer events to background
|
||||
// windows (unless we grab, which will break *everything*).
|
||||
// The only solution is to poll.
|
||||
// Note 2: this driver only supports absolute positions. Relative motion
|
||||
// is faked through SetPosition. This is called automatically when
|
||||
// NativeWindow.CursorVisible = false, otherwise it must be called
|
||||
// by the user.
|
||||
// Note 3: this driver cannot drive the mouse wheel reliably.
|
||||
// See comments in ProcessEvents() for more information.
|
||||
// (If someone knows of a solution, please tell!)
|
||||
sealed class X11Mouse : IMouseDriver2
|
||||
{
|
||||
readonly IntPtr display;
|
||||
readonly IntPtr root_window;
|
||||
MouseState mouse = new MouseState();
|
||||
|
||||
// When the mouse warps, "detach" the current location
|
||||
// from the pointer.
|
||||
bool mouse_detached;
|
||||
int mouse_detached_x, mouse_detached_y;
|
||||
|
||||
public X11Mouse()
|
||||
{
|
||||
Debug.WriteLine("Using X11Mouse.");
|
||||
mouse.IsConnected = true;
|
||||
display = API.DefaultDisplay;
|
||||
root_window = Functions.XRootWindow(display, Functions.XDefaultScreen(display));
|
||||
}
|
||||
|
||||
public MouseState GetState()
|
||||
{
|
||||
ProcessEvents();
|
||||
return mouse;
|
||||
}
|
||||
|
||||
public MouseState GetState(int index)
|
||||
{
|
||||
ProcessEvents();
|
||||
// X11Mouse supports only one device
|
||||
if (index == 0)
|
||||
return mouse;
|
||||
else
|
||||
return new MouseState();
|
||||
}
|
||||
|
||||
public void SetPosition(double x, double y)
|
||||
{
|
||||
// Update the current location, otherwise the pointer
|
||||
// may become locked (for instance, if we call
|
||||
// SetPosition too often, like X11GLNative does).
|
||||
ProcessEvents();
|
||||
|
||||
using (new XLock(display))
|
||||
{
|
||||
// Mark the expected warp-event so it can be ignored.
|
||||
mouse_detached = true;
|
||||
mouse_detached_x = (int)x;
|
||||
mouse_detached_y = (int)y;
|
||||
|
||||
Functions.XWarpPointer(display,
|
||||
IntPtr.Zero, root_window, 0, 0, 0, 0, (int)x, (int)y);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteBit(MouseButton offset, int enabled)
|
||||
{
|
||||
if (enabled != 0)
|
||||
mouse.EnableBit((int)offset);
|
||||
else
|
||||
mouse.DisableBit((int)offset);
|
||||
}
|
||||
|
||||
void ProcessEvents()
|
||||
{
|
||||
IntPtr root, child;
|
||||
int root_x, root_y, win_x, win_y;
|
||||
int buttons;
|
||||
|
||||
using (new XLock(display))
|
||||
{
|
||||
IntPtr window = root_window;
|
||||
Functions.XQueryPointer(display, window, out root, out child,
|
||||
out root_x, out root_y, out win_x, out win_y, out buttons);
|
||||
|
||||
if (!mouse_detached)
|
||||
{
|
||||
mouse.X = root_x;
|
||||
mouse.Y = root_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
mouse.X += (int)root_x - mouse_detached_x;
|
||||
mouse.Y += (int)root_y - mouse_detached_y;
|
||||
mouse_detached_x = root_x;
|
||||
mouse_detached_y = root_y;
|
||||
}
|
||||
WriteBit(MouseButton.Left, buttons & (int)MouseMask.Button1Mask);
|
||||
WriteBit(MouseButton.Middle, buttons & (int)MouseMask.Button2Mask);
|
||||
WriteBit(MouseButton.Right, buttons & (int)MouseMask.Button3Mask);
|
||||
// Note: this will never work right, wheel events have a duration of 0
|
||||
// (yes, zero). They are impposible to catch via polling.
|
||||
// After spending a week on this, I simply don't care anymore.
|
||||
// If someone can fix it, please do.
|
||||
// Note 2: I have tried passively grabbing those buttons - no go (BadAccess).
|
||||
// Maybe I am doing something wrong with the grab.
|
||||
//if ((buttons & (int)MouseMask.Button4Mask) != 0)
|
||||
// mouse.WheelPrecise++;
|
||||
//if ((buttons & (int)MouseMask.Button5Mask) != 0)
|
||||
// mouse.WheelPrecise--;
|
||||
WriteBit(MouseButton.Button1, buttons & (int)MouseMask.Button6Mask);
|
||||
WriteBit(MouseButton.Button2, buttons & (int)MouseMask.Button7Mask);
|
||||
WriteBit(MouseButton.Button3, buttons & (int)MouseMask.Button8Mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,263 +1,263 @@
|
|||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
// Todo: multi-mouse support. Right now we aggregate all data into a single mouse device.
|
||||
// This should be easy: just read the device id and route the data to the correct device.
|
||||
sealed class XI2Mouse : IMouseDriver2
|
||||
{
|
||||
List<MouseState> mice = new List<MouseState>();
|
||||
Dictionary<int, int> rawids = new Dictionary<int, int>(); // maps raw ids to mouse ids
|
||||
internal readonly X11WindowInfo window;
|
||||
static int XIOpCode;
|
||||
|
||||
static readonly Functions.EventPredicate PredicateImpl = IsEventValid;
|
||||
readonly IntPtr Predicate = Marshal.GetFunctionPointerForDelegate(PredicateImpl);
|
||||
|
||||
// Store information on a mouse warp event, so it can be ignored.
|
||||
struct MouseWarp : IEquatable<MouseWarp>
|
||||
{
|
||||
public MouseWarp(double x, double y) { X = x; Y = y; }
|
||||
double X, Y;
|
||||
public bool Equals(MouseWarp warp) { return X == warp.X && Y == warp.Y; }
|
||||
}
|
||||
MouseWarp? mouse_warp_event;
|
||||
int mouse_warp_event_count;
|
||||
|
||||
public XI2Mouse()
|
||||
{
|
||||
Debug.WriteLine("Using XI2Mouse.");
|
||||
|
||||
using (new XLock(API.DefaultDisplay))
|
||||
{
|
||||
window = new X11WindowInfo();
|
||||
window.Display = API.DefaultDisplay;
|
||||
window.Screen = Functions.XDefaultScreen(window.Display);
|
||||
window.RootWindow = Functions.XRootWindow(window.Display, window.Screen);
|
||||
window.Handle = window.RootWindow;
|
||||
}
|
||||
|
||||
if (!IsSupported(window.Display))
|
||||
throw new NotSupportedException("XInput2 not supported.");
|
||||
|
||||
using (XIEventMask mask = new XIEventMask(1, XIEventMasks.RawButtonPressMask |
|
||||
XIEventMasks.RawButtonReleaseMask | XIEventMasks.RawMotionMask))
|
||||
{
|
||||
Functions.XISelectEvents(window.Display, window.Handle, mask);
|
||||
Functions.XISelectEvents(window.Display, window.RootWindow, mask);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks whether XInput2 is supported on the specified display.
|
||||
// If a display is not specified, the default display is used.
|
||||
internal static bool IsSupported(IntPtr display)
|
||||
{
|
||||
if (display == IntPtr.Zero)
|
||||
display = API.DefaultDisplay;
|
||||
|
||||
using (new XLock(display))
|
||||
{
|
||||
int major, ev, error;
|
||||
if (Functions.XQueryExtension(display, "XInputExtension", out major, out ev, out error) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
XIOpCode = major;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region IMouseDriver2 Members
|
||||
|
||||
public MouseState GetState()
|
||||
{
|
||||
ProcessEvents();
|
||||
MouseState master = new MouseState();
|
||||
foreach (MouseState ms in mice)
|
||||
{
|
||||
master.MergeBits(ms);
|
||||
}
|
||||
return master;
|
||||
}
|
||||
|
||||
public MouseState GetState(int index)
|
||||
{
|
||||
ProcessEvents();
|
||||
if (mice.Count > index)
|
||||
return mice[index];
|
||||
else
|
||||
return new MouseState();
|
||||
}
|
||||
|
||||
public void SetPosition(double x, double y)
|
||||
{
|
||||
using (new XLock(window.Display))
|
||||
{
|
||||
Functions.XWarpPointer(window.Display,
|
||||
IntPtr.Zero, window.RootWindow, 0, 0, 0, 0, (int)x, (int)y);
|
||||
|
||||
// Mark the expected warp-event so it can be ignored.
|
||||
if (mouse_warp_event == null)
|
||||
mouse_warp_event_count = 0;
|
||||
mouse_warp_event_count++;
|
||||
mouse_warp_event = new MouseWarp((int)x, (int)y);
|
||||
}
|
||||
|
||||
ProcessEvents();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
bool CheckMouseWarp(double x, double y)
|
||||
{
|
||||
// Check if a mouse warp with the specified destination exists.
|
||||
bool is_warp =
|
||||
mouse_warp_event.HasValue &&
|
||||
mouse_warp_event.Value.Equals(new MouseWarp((int)x, (int)y));
|
||||
|
||||
if (is_warp && --mouse_warp_event_count <= 0)
|
||||
mouse_warp_event = null;
|
||||
|
||||
return is_warp;
|
||||
}
|
||||
|
||||
void ProcessEvents()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
XEvent e = new XEvent();
|
||||
XGenericEventCookie cookie;
|
||||
|
||||
using (new XLock(window.Display))
|
||||
{
|
||||
if (!Functions.XCheckIfEvent(window.Display, ref e, Predicate, new IntPtr(XIOpCode)))
|
||||
return;
|
||||
|
||||
cookie = e.GenericEventCookie;
|
||||
if (Functions.XGetEventData(window.Display, ref cookie) != 0)
|
||||
{
|
||||
XIRawEvent raw = (XIRawEvent)
|
||||
Marshal.PtrToStructure(cookie.data, typeof(XIRawEvent));
|
||||
|
||||
if (!rawids.ContainsKey(raw.deviceid))
|
||||
{
|
||||
mice.Add(new MouseState());
|
||||
rawids.Add(raw.deviceid, mice.Count - 1);
|
||||
}
|
||||
MouseState state = mice[rawids[raw.deviceid]];
|
||||
|
||||
switch (raw.evtype)
|
||||
{
|
||||
case XIEventType.RawMotion:
|
||||
double x = 0, y = 0;
|
||||
if (IsBitSet(raw.valuators.mask, 0))
|
||||
{
|
||||
x = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 0));
|
||||
}
|
||||
if (IsBitSet(raw.valuators.mask, 1))
|
||||
{
|
||||
y = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 8));
|
||||
}
|
||||
|
||||
if (!CheckMouseWarp(x, y))
|
||||
{
|
||||
state.X += (int)x;
|
||||
state.Y += (int)y;
|
||||
}
|
||||
break;
|
||||
|
||||
case XIEventType.RawButtonPress:
|
||||
switch (raw.detail)
|
||||
{
|
||||
case 1: state.EnableBit((int)MouseButton.Left); break;
|
||||
case 2: state.EnableBit((int)MouseButton.Middle); break;
|
||||
case 3: state.EnableBit((int)MouseButton.Right); break;
|
||||
case 4: state.WheelPrecise++; break;
|
||||
case 5: state.WheelPrecise--; break;
|
||||
case 6: state.EnableBit((int)MouseButton.Button1); break;
|
||||
case 7: state.EnableBit((int)MouseButton.Button2); break;
|
||||
case 8: state.EnableBit((int)MouseButton.Button3); break;
|
||||
case 9: state.EnableBit((int)MouseButton.Button4); break;
|
||||
case 10: state.EnableBit((int)MouseButton.Button5); break;
|
||||
case 11: state.EnableBit((int)MouseButton.Button6); break;
|
||||
case 12: state.EnableBit((int)MouseButton.Button7); break;
|
||||
case 13: state.EnableBit((int)MouseButton.Button8); break;
|
||||
case 14: state.EnableBit((int)MouseButton.Button9); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case XIEventType.RawButtonRelease:
|
||||
switch (raw.detail)
|
||||
{
|
||||
case 1: state.DisableBit((int)MouseButton.Left); break;
|
||||
case 2: state.DisableBit((int)MouseButton.Middle); break;
|
||||
case 3: state.DisableBit((int)MouseButton.Right); break;
|
||||
case 6: state.DisableBit((int)MouseButton.Button1); break;
|
||||
case 7: state.DisableBit((int)MouseButton.Button2); break;
|
||||
case 8: state.DisableBit((int)MouseButton.Button3); break;
|
||||
case 9: state.DisableBit((int)MouseButton.Button4); break;
|
||||
case 10: state.DisableBit((int)MouseButton.Button5); break;
|
||||
case 11: state.DisableBit((int)MouseButton.Button6); break;
|
||||
case 12: state.DisableBit((int)MouseButton.Button7); break;
|
||||
case 13: state.DisableBit((int)MouseButton.Button8); break;
|
||||
case 14: state.DisableBit((int)MouseButton.Button9); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mice[rawids[raw.deviceid]] = state;
|
||||
}
|
||||
Functions.XFreeEventData(window.Display, ref cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsEventValid(IntPtr display, ref XEvent e, IntPtr arg)
|
||||
{
|
||||
return e.GenericEventCookie.extension == arg.ToInt32() &&
|
||||
(e.GenericEventCookie.evtype == (int)XIEventType.RawMotion ||
|
||||
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonPress ||
|
||||
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonRelease);
|
||||
}
|
||||
|
||||
static bool IsBitSet(IntPtr mask, int bit)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return (*((byte*)mask + (bit >> 3)) & (1 << (bit & 7))) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region License
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Input;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
// Todo: multi-mouse support. Right now we aggregate all data into a single mouse device.
|
||||
// This should be easy: just read the device id and route the data to the correct device.
|
||||
sealed class XI2Mouse : IMouseDriver2
|
||||
{
|
||||
List<MouseState> mice = new List<MouseState>();
|
||||
Dictionary<int, int> rawids = new Dictionary<int, int>(); // maps raw ids to mouse ids
|
||||
internal readonly X11WindowInfo window;
|
||||
static int XIOpCode;
|
||||
|
||||
static readonly Functions.EventPredicate PredicateImpl = IsEventValid;
|
||||
readonly IntPtr Predicate = Marshal.GetFunctionPointerForDelegate(PredicateImpl);
|
||||
|
||||
// Store information on a mouse warp event, so it can be ignored.
|
||||
struct MouseWarp : IEquatable<MouseWarp>
|
||||
{
|
||||
public MouseWarp(double x, double y) { X = x; Y = y; }
|
||||
double X, Y;
|
||||
public bool Equals(MouseWarp warp) { return X == warp.X && Y == warp.Y; }
|
||||
}
|
||||
MouseWarp? mouse_warp_event;
|
||||
int mouse_warp_event_count;
|
||||
|
||||
public XI2Mouse()
|
||||
{
|
||||
Debug.WriteLine("Using XI2Mouse.");
|
||||
|
||||
using (new XLock(API.DefaultDisplay))
|
||||
{
|
||||
window = new X11WindowInfo();
|
||||
window.Display = API.DefaultDisplay;
|
||||
window.Screen = Functions.XDefaultScreen(window.Display);
|
||||
window.RootWindow = Functions.XRootWindow(window.Display, window.Screen);
|
||||
window.Handle = window.RootWindow;
|
||||
}
|
||||
|
||||
if (!IsSupported(window.Display))
|
||||
throw new NotSupportedException("XInput2 not supported.");
|
||||
|
||||
using (XIEventMask mask = new XIEventMask(1, XIEventMasks.RawButtonPressMask |
|
||||
XIEventMasks.RawButtonReleaseMask | XIEventMasks.RawMotionMask))
|
||||
{
|
||||
Functions.XISelectEvents(window.Display, window.Handle, mask);
|
||||
Functions.XISelectEvents(window.Display, window.RootWindow, mask);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks whether XInput2 is supported on the specified display.
|
||||
// If a display is not specified, the default display is used.
|
||||
internal static bool IsSupported(IntPtr display)
|
||||
{
|
||||
if (display == IntPtr.Zero)
|
||||
display = API.DefaultDisplay;
|
||||
|
||||
using (new XLock(display))
|
||||
{
|
||||
int major, ev, error;
|
||||
if (Functions.XQueryExtension(display, "XInputExtension", out major, out ev, out error) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
XIOpCode = major;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region IMouseDriver2 Members
|
||||
|
||||
public MouseState GetState()
|
||||
{
|
||||
ProcessEvents();
|
||||
MouseState master = new MouseState();
|
||||
foreach (MouseState ms in mice)
|
||||
{
|
||||
master.MergeBits(ms);
|
||||
}
|
||||
return master;
|
||||
}
|
||||
|
||||
public MouseState GetState(int index)
|
||||
{
|
||||
ProcessEvents();
|
||||
if (mice.Count > index)
|
||||
return mice[index];
|
||||
else
|
||||
return new MouseState();
|
||||
}
|
||||
|
||||
public void SetPosition(double x, double y)
|
||||
{
|
||||
using (new XLock(window.Display))
|
||||
{
|
||||
Functions.XWarpPointer(window.Display,
|
||||
IntPtr.Zero, window.RootWindow, 0, 0, 0, 0, (int)x, (int)y);
|
||||
|
||||
// Mark the expected warp-event so it can be ignored.
|
||||
if (mouse_warp_event == null)
|
||||
mouse_warp_event_count = 0;
|
||||
mouse_warp_event_count++;
|
||||
mouse_warp_event = new MouseWarp((int)x, (int)y);
|
||||
}
|
||||
|
||||
ProcessEvents();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
bool CheckMouseWarp(double x, double y)
|
||||
{
|
||||
// Check if a mouse warp with the specified destination exists.
|
||||
bool is_warp =
|
||||
mouse_warp_event.HasValue &&
|
||||
mouse_warp_event.Value.Equals(new MouseWarp((int)x, (int)y));
|
||||
|
||||
if (is_warp && --mouse_warp_event_count <= 0)
|
||||
mouse_warp_event = null;
|
||||
|
||||
return is_warp;
|
||||
}
|
||||
|
||||
void ProcessEvents()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
XEvent e = new XEvent();
|
||||
XGenericEventCookie cookie;
|
||||
|
||||
using (new XLock(window.Display))
|
||||
{
|
||||
if (!Functions.XCheckIfEvent(window.Display, ref e, Predicate, new IntPtr(XIOpCode)))
|
||||
return;
|
||||
|
||||
cookie = e.GenericEventCookie;
|
||||
if (Functions.XGetEventData(window.Display, ref cookie) != 0)
|
||||
{
|
||||
XIRawEvent raw = (XIRawEvent)
|
||||
Marshal.PtrToStructure(cookie.data, typeof(XIRawEvent));
|
||||
|
||||
if (!rawids.ContainsKey(raw.deviceid))
|
||||
{
|
||||
mice.Add(new MouseState());
|
||||
rawids.Add(raw.deviceid, mice.Count - 1);
|
||||
}
|
||||
MouseState state = mice[rawids[raw.deviceid]];
|
||||
|
||||
switch (raw.evtype)
|
||||
{
|
||||
case XIEventType.RawMotion:
|
||||
double x = 0, y = 0;
|
||||
if (IsBitSet(raw.valuators.mask, 0))
|
||||
{
|
||||
x = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 0));
|
||||
}
|
||||
if (IsBitSet(raw.valuators.mask, 1))
|
||||
{
|
||||
y = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 8));
|
||||
}
|
||||
|
||||
if (!CheckMouseWarp(x, y))
|
||||
{
|
||||
state.X += (int)x;
|
||||
state.Y += (int)y;
|
||||
}
|
||||
break;
|
||||
|
||||
case XIEventType.RawButtonPress:
|
||||
switch (raw.detail)
|
||||
{
|
||||
case 1: state.EnableBit((int)MouseButton.Left); break;
|
||||
case 2: state.EnableBit((int)MouseButton.Middle); break;
|
||||
case 3: state.EnableBit((int)MouseButton.Right); break;
|
||||
case 4: state.WheelPrecise++; break;
|
||||
case 5: state.WheelPrecise--; break;
|
||||
case 6: state.EnableBit((int)MouseButton.Button1); break;
|
||||
case 7: state.EnableBit((int)MouseButton.Button2); break;
|
||||
case 8: state.EnableBit((int)MouseButton.Button3); break;
|
||||
case 9: state.EnableBit((int)MouseButton.Button4); break;
|
||||
case 10: state.EnableBit((int)MouseButton.Button5); break;
|
||||
case 11: state.EnableBit((int)MouseButton.Button6); break;
|
||||
case 12: state.EnableBit((int)MouseButton.Button7); break;
|
||||
case 13: state.EnableBit((int)MouseButton.Button8); break;
|
||||
case 14: state.EnableBit((int)MouseButton.Button9); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case XIEventType.RawButtonRelease:
|
||||
switch (raw.detail)
|
||||
{
|
||||
case 1: state.DisableBit((int)MouseButton.Left); break;
|
||||
case 2: state.DisableBit((int)MouseButton.Middle); break;
|
||||
case 3: state.DisableBit((int)MouseButton.Right); break;
|
||||
case 6: state.DisableBit((int)MouseButton.Button1); break;
|
||||
case 7: state.DisableBit((int)MouseButton.Button2); break;
|
||||
case 8: state.DisableBit((int)MouseButton.Button3); break;
|
||||
case 9: state.DisableBit((int)MouseButton.Button4); break;
|
||||
case 10: state.DisableBit((int)MouseButton.Button5); break;
|
||||
case 11: state.DisableBit((int)MouseButton.Button6); break;
|
||||
case 12: state.DisableBit((int)MouseButton.Button7); break;
|
||||
case 13: state.DisableBit((int)MouseButton.Button8); break;
|
||||
case 14: state.DisableBit((int)MouseButton.Button9); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mice[rawids[raw.deviceid]] = state;
|
||||
}
|
||||
Functions.XFreeEventData(window.Display, ref cookie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsEventValid(IntPtr display, ref XEvent e, IntPtr arg)
|
||||
{
|
||||
return e.GenericEventCookie.extension == arg.ToInt32() &&
|
||||
(e.GenericEventCookie.evtype == (int)XIEventType.RawMotion ||
|
||||
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonPress ||
|
||||
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonRelease);
|
||||
}
|
||||
|
||||
static bool IsBitSet(IntPtr mask, int bit)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
return (*((byte*)mask + (bit >> 3)) & (1 << (bit & 7))) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,120 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
Loading…
Reference in a new issue