Fixed line endings
This commit is contained in:
parent
fb86334835
commit
459313dca8
11 changed files with 3988 additions and 3988 deletions
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