Added X11 Mouse support. X11 Keyboard support is faster now.
Made GameWindow.Dispose() virtual.
This commit is contained in:
parent
da377f3c23
commit
ec34bed972
11 changed files with 290 additions and 92 deletions
|
@ -680,9 +680,13 @@ namespace OpenTK
|
|||
|
||||
#region --- IDisposable Members ---
|
||||
|
||||
public void Dispose()
|
||||
/// <summary>
|
||||
/// Disposes of the GameWindow, releasing all resources consumed by it.
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool manual)
|
||||
|
@ -710,6 +714,11 @@ namespace OpenTK
|
|||
}
|
||||
}
|
||||
|
||||
~GameWindow()
|
||||
{
|
||||
this.Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@ namespace OpenTK
|
|||
}
|
||||
else if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
inputDriver = new OpenTK.Platform.X11.X11Input(parent);
|
||||
inputDriver = new OpenTK.Platform.X11.X11Input(
|
||||
parent is OpenTK.Platform.X11.WindowInfo ? (OpenTK.Platform.X11.WindowInfo)parent :
|
||||
parent is OpenTK.Platform.WindowInfo ? (OpenTK.Platform.X11.WindowInfo)(parent as OpenTK.Platform.WindowInfo) : null);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -137,12 +137,12 @@ namespace OpenTK.Platform
|
|||
implementation.CopyInfoFrom(info);
|
||||
}
|
||||
|
||||
public static implicit operator Windows.WindowInfo (WindowInfo info)
|
||||
public static explicit operator Windows.WindowInfo(WindowInfo info)
|
||||
{
|
||||
return (Windows.WindowInfo)info.implementation;
|
||||
}
|
||||
|
||||
public static implicit operator X11.WindowInfo (WindowInfo info)
|
||||
public static explicit operator X11.WindowInfo(WindowInfo info)
|
||||
{
|
||||
return (X11.WindowInfo)info.implementation;
|
||||
}
|
||||
|
|
|
@ -215,7 +215,7 @@ namespace OpenTK.Platform.Windows
|
|||
public IWindowInfo WindowInfo
|
||||
{
|
||||
get { return window; }
|
||||
private set { window = value as WindowInfo; }
|
||||
//private set { window = value as WindowInfo; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -288,7 +288,7 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
public void OnCreate(EventArgs e)
|
||||
{
|
||||
this.WindowInfo = new WindowInfo(this);
|
||||
this.window = new WindowInfo(this);
|
||||
|
||||
Debug.Print("Window created: {0}", window);
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace OpenTK.Platform.X11
|
|||
[DllImport(_dll_name, EntryPoint = "XRootWindow")]
|
||||
public static extern Window RootWindow(Display display, int screen);
|
||||
|
||||
[Obsolete("Use XCreateWindow instead")]
|
||||
[DllImport(_dll_name, EntryPoint = "XCreateWindow")]
|
||||
public extern static Window CreateWindow(
|
||||
Display display,
|
||||
|
@ -555,7 +556,7 @@ XF86VidModeGetGammaRampSize(
|
|||
|
||||
#region public class SetWindowAttributes
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[StructLayout(LayoutKind.Sequential), Obsolete("Use XSetWindowAttributes instead")]
|
||||
public class SetWindowAttributes
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -1063,8 +1064,7 @@ XF86VidModeGetGammaRampSize(
|
|||
VisualAllMask = 0x1FF,
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
#region public enum MouseMask
|
||||
|
||||
public enum MouseMask
|
||||
{
|
||||
|
@ -1088,6 +1088,10 @@ XF86VidModeGetGammaRampSize(
|
|||
Mod5Mask = (1 << 7),
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public enum MouseButton
|
||||
|
||||
public enum MouseButton
|
||||
{
|
||||
Button1 = 1,
|
||||
|
@ -1096,4 +1100,111 @@ XF86VidModeGetGammaRampSize(
|
|||
Button4 = 4,
|
||||
Button5 = 5,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
public static partial class Functions
|
||||
{
|
||||
#region XCreateWindow
|
||||
|
||||
/// <summary>
|
||||
/// The XCreateWindow function creates an unmapped subwindow for a specified parent window, returns the window ID of the created window, and causes the X server to generate a CreateNotify event. The created window is placed on top in the stacking order with respect to siblings.
|
||||
/// </summary>
|
||||
/// <param name="display">Specifies the connection to the X server.</param>
|
||||
/// <param name="parent">Specifies the parent window.</param>
|
||||
/// <param name="x">Specify the x coordinates, which are the top-left outside corner of the window's borders and are relative to the inside of the parent window's borders.</param>
|
||||
/// <param name="y">Specify the y coordinates, which are the top-left outside corner of the window's borders and are relative to the inside of the parent window's borders.</param>
|
||||
/// <param name="width">Specify the width, which is the created window's inside dimensions and do not include the created window's borders.</param>
|
||||
/// <param name="height">Specify the height, which is the created window's inside dimensions and do not include the created window's borders.</param>
|
||||
/// <param name="border_width">Specifies the width of the created window's border in pixels.</param>
|
||||
/// <param name="depth">Specifies the window's depth. A depth of CopyFromParent means the depth is taken from the parent.</param>
|
||||
/// <param name="class">Specifies the created window's class. You can pass InputOutput, InputOnly, or CopyFromParent. A class of CopyFromParent means the class is taken from the parent.</param>
|
||||
/// <param name="visual">Specifies the visual type. A visual of CopyFromParent means the visual type is taken from the parent.</param>
|
||||
/// <param name="valuemask">Specifies which window attributes are defined in the attributes argument. This mask is the bitwise inclusive OR of the valid attribute mask bits. If valuemask is zero, the attributes are ignored and are not referenced.</param>
|
||||
/// <param name="attributes">Specifies the structure from which the values (as specified by the value mask) are to be taken. The value mask should have the appropriate bits set to indicate which attributes have been set in the structure.</param>
|
||||
/// <returns>The window ID of the created window.</returns>
|
||||
/// <remarks>
|
||||
/// The coordinate system has the X axis horizontal and the Y axis vertical with the origin [0, 0] at the upper-left corner. Coordinates are integral, in terms of pixels, and coincide with pixel centers. Each window and pixmap has its own coordinate system. For a window, the origin is inside the border at the inside, upper-left corner.
|
||||
/// <para>The border_width for an InputOnly window must be zero, or a BadMatch error results. For class InputOutput, the visual type and depth must be a combination supported for the screen, or a BadMatch error results. The depth need not be the same as the parent, but the parent must not be a window of class InputOnly, or a BadMatch error results. For an InputOnly window, the depth must be zero, and the visual must be one supported by the screen. If either condition is not met, a BadMatch error results. The parent window, however, may have any depth and class. If you specify any invalid window attribute for a window, a BadMatch error results. </para>
|
||||
/// <para>The created window is not yet displayed (mapped) on the user's display. To display the window, call XMapWindow(). The new window initially uses the same cursor as its parent. A new cursor can be defined for the new window by calling XDefineCursor(). The window will not be visible on the screen unless it and all of its ancestors are mapped and it is not obscured by any of its ancestors. </para>
|
||||
/// <para>XCreateWindow can generate BadAlloc BadColor, BadCursor, BadMatch, BadPixmap, BadValue, and BadWindow errors. </para>
|
||||
/// <para>The XCreateSimpleWindow function creates an unmapped InputOutput subwindow for a specified parent window, returns the window ID of the created window, and causes the X server to generate a CreateNotify event. The created window is placed on top in the stacking order with respect to siblings. Any part of the window that extends outside its parent window is clipped. The border_width for an InputOnly window must be zero, or a BadMatch error results. XCreateSimpleWindow inherits its depth, class, and visual from its parent. All other window attributes, except background and border, have their default values. </para>
|
||||
/// <para>XCreateSimpleWindow can generate BadAlloc, BadMatch, BadValue, and BadWindow errors.</para>
|
||||
/// </remarks>
|
||||
[DllImport("libX11", EntryPoint = "XCreateWindow"), CLSCompliant(false)]
|
||||
public extern static Window XCreateWindow(Display display, Window parent,
|
||||
int x, int y, int width, int height, int border_width, int depth,
|
||||
int @class, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes);
|
||||
|
||||
#endregion
|
||||
|
||||
#region XQueryKeymap
|
||||
|
||||
/// <summary>
|
||||
/// The XQueryKeymap() function returns a bit vector for the logical state of the keyboard, where each bit set to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes. Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least-significant bit in the byte representing key 8N.
|
||||
/// </summary>
|
||||
/// <param name="display">Specifies the connection to the X server.</param>
|
||||
/// <param name="keys">Returns an array of bytes that identifies which keys are pressed down. Each bit represents one key of the keyboard.</param>
|
||||
/// <remarks>Note that the logical state of a device (as seen by client applications) may lag the physical state if device event processing is frozen.</remarks>
|
||||
[DllImport("libX11", EntryPoint = "XQueryKeymap")]
|
||||
extern public static void XQueryKeymap(IntPtr display, [MarshalAs(UnmanagedType.LPArray, SizeConst = 32), In, Out] Keymap keys);
|
||||
|
||||
/// <summary>
|
||||
/// The XQueryKeymap() function returns a bit vector for the logical state of the keyboard, where each bit set to 1 indicates that the corresponding key is currently pressed down. The vector is represented as 32 bytes. Byte N (from 0) contains the bits for keys 8N to 8N + 7 with the least-significant bit in the byte representing key 8N.
|
||||
/// </summary>
|
||||
/// <param name="display">Specifies the connection to the X server.</param>
|
||||
/// <param name="keys">Returns an array of bytes that identifies which keys are pressed down. Each bit represents one key of the keyboard.</param>
|
||||
/// <remarks>Note that the logical state of a device (as seen by client applications) may lag the physical state if device event processing is frozen.</remarks>
|
||||
[DllImport("libX11", EntryPoint = "XQueryKeymap")]
|
||||
extern public static void XQueryKeymap(IntPtr display, byte[] keys);
|
||||
|
||||
#endregion
|
||||
|
||||
#region XMaskEvent
|
||||
|
||||
/// <summary>
|
||||
/// The XMaskEvent() function searches the event queue for the events associated with the specified mask. When it finds a match, XMaskEvent() removes that event and copies it into the specified XEvent structure. The other events stored in the queue are not discarded. If the event you requested is not in the queue, XMaskEvent() flushes the output buffer and blocks until one is received.
|
||||
/// </summary>
|
||||
/// <param name="display">Specifies the connection to the X server.</param>
|
||||
/// <param name="event_mask">Specifies the event mask.</param>
|
||||
/// <param name="e">Returns the matched event's associated structure.</param>
|
||||
[DllImport("libX11", EntryPoint = "XMaskEvent")]
|
||||
extern public static void XMaskEvent(IntPtr display, EventMask event_mask, ref XEvent e);
|
||||
|
||||
#endregion
|
||||
|
||||
#region XPutBackEvent
|
||||
|
||||
/// <summary>
|
||||
/// The XPutBackEvent() function pushes an event back onto the head of the display's event queue by copying the event into the queue. This can be useful if you read an event and then decide that you would rather deal with it later. There is no limit to the number of times in succession that you can call XPutBackEvent().
|
||||
/// </summary>
|
||||
/// <param name="display">Specifies the connection to the X server.</param>
|
||||
/// <param name="event">Specifies the event.</param>
|
||||
[DllImport("libX11", EntryPoint = "XPutBackEvent")]
|
||||
public static extern void XPutBackEvent(IntPtr display, ref XEvent @event);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Keymap
|
||||
{
|
||||
unsafe fixed byte bits[32];
|
||||
|
||||
public bool this[KeyCode key]
|
||||
{
|
||||
get
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (Keymap* ptr = &this)
|
||||
{
|
||||
return ((ptr->bits[key / 8] >> (key % 8)) & 0x01) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
|
|||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
public class Functions
|
||||
public static partial class Functions
|
||||
{
|
||||
[DllImport("libX11", EntryPoint = "XOpenDisplay")]
|
||||
public extern static IntPtr XOpenDisplay(IntPtr display);
|
||||
|
@ -14,8 +14,8 @@ namespace OpenTK.Platform.X11
|
|||
[DllImport("libX11", EntryPoint = "XSynchronize")]
|
||||
public extern static IntPtr XSynchronize(IntPtr display, bool onoff);
|
||||
|
||||
[DllImport("libX11", EntryPoint = "XCreateWindow"), CLSCompliant(false)]
|
||||
public extern static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes);
|
||||
//[DllImport("libX11", EntryPoint = "XCreateWindow"), CLSCompliant(false)]
|
||||
//public extern static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, UIntPtr valuemask, ref XSetWindowAttributes attributes);
|
||||
[DllImport("libX11", EntryPoint = "XCreateWindow")]
|
||||
public extern static IntPtr XCreateWindow(IntPtr display, IntPtr parent, int x, int y, int width, int height, int border_width, int depth, int xclass, IntPtr visual, IntPtr valuemask, ref XSetWindowAttributes attributes);
|
||||
|
||||
|
|
|
@ -20,9 +20,10 @@ namespace OpenTK.Platform.X11
|
|||
private IntPtr handle, topLevelWindow;
|
||||
private IntPtr rootWindow, display;
|
||||
private int screen;
|
||||
private WindowInfo parent;
|
||||
private X11.WindowInfo parent;
|
||||
private XVisualInfo visinfo;
|
||||
private static Type xplatui;
|
||||
private EventMask eventMask;
|
||||
|
||||
public WindowInfo()
|
||||
{
|
||||
|
@ -90,7 +91,7 @@ namespace OpenTK.Platform.X11
|
|||
if (window == null)
|
||||
throw new ArgumentException("GameWindow cannot be null.");
|
||||
|
||||
return this.GetInfoFrom(window.WindowInfo as X11.WindowInfo);
|
||||
return this.GetInfoFrom(window.WindowInfo);
|
||||
}
|
||||
|
||||
public IWindowInfo GetInfoFrom(IWindowInfo info)
|
||||
|
@ -107,25 +108,31 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
public void CopyInfoFrom(IWindowInfo info)
|
||||
{
|
||||
if (info == null)
|
||||
throw new ArgumentException("IWindowInfo info cannot be null.");
|
||||
this.Handle = info.Handle;
|
||||
this.Parent = info.Parent;
|
||||
|
||||
WindowInfo winfo = info as WindowInfo;
|
||||
X11.WindowInfo winfo = info as X11.WindowInfo ?? (X11.WindowInfo)(info as Platform.WindowInfo);
|
||||
|
||||
this.RootWindow = winfo.RootWindow;
|
||||
this.TopLevelWindow = winfo.TopLevelWindow;
|
||||
this.Display = winfo.Display;
|
||||
this.Screen = winfo.Screen;
|
||||
this.VisualInfo = winfo.VisualInfo;
|
||||
this.EventMask = winfo.EventMask;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public IntPtr RootWindow { get { return rootWindow; } internal set { rootWindow = value; } }
|
||||
public IntPtr TopLevelWindow { get { return topLevelWindow; } internal set { topLevelWindow = value; } }
|
||||
public IntPtr ParentHandle { get { return parent.Handle; } internal set { parent.Handle = value; } }
|
||||
public IntPtr Display { get { return display; } internal set { display = value; } }
|
||||
public int Screen { get { return screen; } internal set { screen = value; } }
|
||||
public XVisualInfo VisualInfo { get { return visinfo; } internal set { visinfo = value; } }
|
||||
public EventMask EventMask { get { return eventMask; } internal set { eventMask = value; } }
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
@ -145,6 +152,7 @@ namespace OpenTK.Platform.X11
|
|||
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
|
||||
this.Screen = (int)xplatui.GetField("ScreenNo",
|
||||
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,6 +131,10 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
case XEventName.KeyPress:
|
||||
case XEventName.KeyRelease:
|
||||
case XEventName.MotionNotify:
|
||||
case XEventName.ButtonPress:
|
||||
case XEventName.ButtonRelease:
|
||||
Functions.XPutBackEvent(window.Display, ref e);
|
||||
return;
|
||||
|
||||
default:
|
||||
|
@ -267,8 +271,12 @@ namespace OpenTK.Platform.X11
|
|||
attributes.border_pixel = IntPtr.Zero;
|
||||
attributes.colormap =
|
||||
API.CreateColormap(window.Display, window.RootWindow, window.VisualInfo.visual, 0/*AllocNone*/);
|
||||
attributes.event_mask =
|
||||
(IntPtr)(EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask);
|
||||
window.EventMask =
|
||||
EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
|
||||
EventMask.KeyReleaseMask | EventMask.KeyPressMask |
|
||||
EventMask.PointerMotionMask | EventMask.PointerMotionHintMask |
|
||||
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
|
||||
attributes.event_mask = (IntPtr)window.EventMask;
|
||||
|
||||
uint mask = (uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
|
||||
(uint)SetWindowValuemask.BackPixel | (uint)SetWindowValuemask.BorderPixel;
|
||||
|
|
|
@ -10,6 +10,7 @@ using System.Text;
|
|||
|
||||
using OpenTK.Input;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
|
@ -19,12 +20,16 @@ namespace OpenTK.Platform.X11
|
|||
/// </summary>
|
||||
internal sealed class X11Input : IInputDriver
|
||||
{
|
||||
private X11Keyboard keyboardDriver;
|
||||
private X11Mouse mouseDriver;
|
||||
private X11.WindowInfo window;
|
||||
X11Keyboard keyboardDriver;
|
||||
X11Mouse mouseDriver;
|
||||
X11.WindowInfo window;
|
||||
|
||||
XEvent e = new XEvent();
|
||||
|
||||
Thread pollingThread;
|
||||
|
||||
bool disposed, disposing;
|
||||
|
||||
#region --- Constructors ---
|
||||
|
||||
/// <summary>
|
||||
|
@ -33,7 +38,7 @@ namespace OpenTK.Platform.X11
|
|||
/// the device specific drivers (Keyboard, Mouse, Hid).
|
||||
/// </summary>
|
||||
/// <param name="attach">The window which the InputDriver will attach itself on.</param>
|
||||
public X11Input(IWindowInfo attach)
|
||||
public X11Input(X11.WindowInfo attach)
|
||||
{
|
||||
Debug.WriteLine("Initalizing X11 input driver.");
|
||||
Debug.Indent();
|
||||
|
@ -42,63 +47,94 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
throw new ArgumentException("A valid parent window must be defined, in order to create an X11Input driver.");
|
||||
}
|
||||
|
||||
window = new X11.WindowInfo(attach);
|
||||
window.Parent = attach;
|
||||
/*
|
||||
Debug.WriteLine("Creating hidden input window.");
|
||||
Debug.Print("Creating hidden input window.");
|
||||
|
||||
SetWindowAttributes wnd_attributes = new SetWindowAttributes();
|
||||
wnd_attributes.background_pixel = 0;
|
||||
wnd_attributes.border_pixel = 0;
|
||||
wnd_attributes.colormap = IntPtr.Zero;
|
||||
wnd_attributes.event_mask = EventMask.KeyPressMask | EventMask.KeyReleaseMask |
|
||||
EventMask.FocusChangeMask;
|
||||
|
||||
CreateWindowMask cw_mask =
|
||||
CreateWindowMask.CWEventMask;
|
||||
|
||||
window = new WindowInfo(parent);
|
||||
|
||||
window.Handle = API.CreateWindow(
|
||||
window.Display,
|
||||
window.Parent.Handle,
|
||||
0, 0,
|
||||
1, 1,
|
||||
0, 0,
|
||||
Constants.InputOnly,
|
||||
//window.VisualInfo.visual,
|
||||
(IntPtr)0,
|
||||
cw_mask,
|
||||
wnd_attributes
|
||||
);
|
||||
XSetWindowAttributes wnd_attr = new XSetWindowAttributes();
|
||||
wnd_attr.background_pixel = IntPtr.Zero;
|
||||
wnd_attr.border_pixel = IntPtr.Zero;
|
||||
//wnd_attr.colormap = IntPtr.Zero;
|
||||
wnd_attr.event_mask = (IntPtr)
|
||||
(EventMask.StructureNotifyMask |
|
||||
EventMask.PointerMotionMask | EventMask.PointerMotionHintMask |
|
||||
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask |
|
||||
EventMask.KeyPressMask | EventMask.KeyReleaseMask);
|
||||
uint cw =
|
||||
(uint)SetWindowValuemask.ColorMap | (uint)SetWindowValuemask.EventMask |
|
||||
(uint)SetWindowValuemask.BackPixel | (uint)SetWindowValuemask.BorderPixel;
|
||||
|
||||
window.Handle = Functions.XCreateWindow(window.Display, window.Parent.Handle,
|
||||
0, 0, 30, 30, 0, Constants.CopyFromParent, Constants.InputOutput,
|
||||
IntPtr.Zero, (UIntPtr)cw, ref wnd_attr);
|
||||
|
||||
if (window.Handle == IntPtr.Zero)
|
||||
{
|
||||
throw new Exception("Could not create input window.");
|
||||
}
|
||||
throw new ApplicationException("Could not create hidden input window.");
|
||||
|
||||
API.MapWindow(window.Display, window.Handle);
|
||||
API.GrabKeyboard(window.Display, window.Handle, false, GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, 0);
|
||||
|
||||
Debug.WriteLine("done! (id: " + window + ")");
|
||||
|
||||
keyboardDriver = new X11Keyboard(window);
|
||||
Functions.XMapWindow(window.Display, window.Handle);
|
||||
*/
|
||||
|
||||
window = attach as Platform.WindowInfo ?? attach as X11.WindowInfo;
|
||||
|
||||
window = attach;
|
||||
keyboardDriver = new X11Keyboard(window);
|
||||
mouseDriver = new X11Mouse(window);
|
||||
// Todo: mask is now specified by hand, hard to keep in sync.
|
||||
API.SelectInput(window.Display, window.Handle, EventMask.StructureNotifyMask |
|
||||
EventMask.SubstructureNotifyMask | EventMask.ExposureMask |
|
||||
EventMask.KeyReleaseMask | EventMask.KeyPressMask |
|
||||
EventMask.PointerMotionMask | EventMask.PointerMotionHintMask |
|
||||
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask);
|
||||
|
||||
Thread pollingThread = new Thread(InternalPoll);
|
||||
//pollingThread.Priority = ThreadPriority.BelowNormal;
|
||||
pollingThread.IsBackground = true;
|
||||
pollingThread.Start();
|
||||
|
||||
Debug.Unindent();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void InternalPoll()
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!disposed)
|
||||
{
|
||||
Functions.XMaskEvent(window.Display,
|
||||
EventMask.PointerMotionMask | EventMask.PointerMotionHintMask |
|
||||
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask |
|
||||
EventMask.KeyPressMask | EventMask.KeyReleaseMask |
|
||||
EventMask.StructureNotifyMask, ref e);
|
||||
|
||||
if (disposed || disposing)
|
||||
return;
|
||||
|
||||
switch (e.type)
|
||||
{
|
||||
case XEventName.KeyPress:
|
||||
case XEventName.KeyRelease:
|
||||
keyboardDriver.ProcessKeyboardEvent(ref e.KeyEvent);
|
||||
break;
|
||||
|
||||
case XEventName.ButtonPress:
|
||||
case XEventName.ButtonRelease:
|
||||
mouseDriver.ProcessButton(ref e.ButtonEvent);
|
||||
break;
|
||||
|
||||
case XEventName.MotionNotify:
|
||||
mouseDriver.ProcessMotion(ref e.MotionEvent);
|
||||
break;
|
||||
|
||||
case XEventName.DestroyNotify:
|
||||
Functions.XPutBackEvent(window.Display, ref e);
|
||||
//pollingThread.Abort();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ThreadAbortException expt)
|
||||
{
|
||||
Functions.XUnmapWindow(window.Display, window.Handle);
|
||||
Functions.XDestroyWindow(window.Display, window.Handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#region --- IInputDriver Members ---
|
||||
|
||||
#region public IList<IInputDevice> InputDevices
|
||||
|
@ -136,28 +172,6 @@ namespace OpenTK.Platform.X11
|
|||
/// </summary>
|
||||
public void Poll()
|
||||
{
|
||||
while (API.CheckMaskEvent(window.Display, EventMask.KeyReleaseMask | EventMask.KeyPressMask, ref e))
|
||||
{
|
||||
keyboardDriver.ProcessKeyboardEvent(e.KeyEvent);
|
||||
}
|
||||
while (API.CheckMaskEvent(window.Display, EventMask.ButtonPressMask | EventMask.ButtonPressMask, ref e))
|
||||
{
|
||||
mouseDriver.ProcessButton(e.ButtonEvent);
|
||||
}
|
||||
while (API.CheckMaskEvent(window.Display, EventMask.PointerMotionMask | EventMask.PointerMotionHintMask, ref e))
|
||||
{
|
||||
mouseDriver.ProcessMotion(e.MotionEvent);
|
||||
}
|
||||
/*
|
||||
if (API.Pending(window.Display) > 0)
|
||||
{
|
||||
Functions.XPeekEvent(window.Display, ref e);
|
||||
if (e.type == XEventName.KeyRelease || e.type == XEventName.KeyPress)
|
||||
{
|
||||
keyboardDriver.ProcessKeyboardEvent(e.KeyEvent);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -168,7 +182,29 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool manual)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
disposing = true;
|
||||
if (pollingThread != null && pollingThread.IsAlive)
|
||||
pollingThread.Abort();
|
||||
|
||||
if (manual)
|
||||
{
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
~X11Input()
|
||||
{
|
||||
this.Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -203,7 +203,7 @@ namespace OpenTK.Platform.X11
|
|||
/// </summary>
|
||||
/// <param name="e">The X11.KeyEvent to process</param>
|
||||
/// <returns>True if the event was processed, false otherwise.</returns>
|
||||
internal bool ProcessKeyboardEvent(X11.XKeyEvent e)
|
||||
internal bool ProcessKeyboardEvent(ref X11.XKeyEvent e)
|
||||
{
|
||||
//int keysym = keysyms[(e.keycode - firstKeyCode) * keysyms_per_keycode].ToInt32();
|
||||
//int keysym2 = keysyms[(e.keycode - firstKeyCode) * keysyms_per_keycode].ToInt32();
|
||||
|
@ -212,7 +212,7 @@ namespace OpenTK.Platform.X11
|
|||
IntPtr keysym = API.LookupKeysym(ref e, 0);
|
||||
IntPtr keysym2 = API.LookupKeysym(ref e, 1);
|
||||
|
||||
Debug.Print("Key down: {0}", e.ToString());
|
||||
//Debug.Print("Key down: {0}", e.ToString());
|
||||
|
||||
int index = keyboards.FindIndex(delegate(Keyboard kb)
|
||||
{
|
||||
|
@ -232,7 +232,7 @@ namespace OpenTK.Platform.X11
|
|||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2);
|
||||
//Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -249,5 +249,29 @@ namespace OpenTK.Platform.X11
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void Poll()
|
||||
{
|
||||
//Keymap map = new Keymap();
|
||||
//X11.Functions.XQueryKeymap(window.Display, map);
|
||||
/*
|
||||
byte[] bits = new byte[32];
|
||||
X11.Functions.XQueryKeymap(window.Display, bits);
|
||||
|
||||
XKeyEvent e = new XKeyEvent();
|
||||
e.display = window.Display;
|
||||
e.window = window.Handle;
|
||||
e.root = window.RootWindow;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
e.keycode = i;
|
||||
ProcessKeyboardEvent(e);
|
||||
|
||||
//if (keymap.ContainsKey((XKey)i))
|
||||
// keyboards[0][keymap[(XKey)i]] = ((bits[i / 8] >> (i % 8)) & 0x01) != 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace OpenTK.Platform.X11
|
|||
/// </summary>
|
||||
/// <param name="e">The X11.XButtonEvent to process.</param>
|
||||
/// <returns>True if the event was processed, false otherwise.</returns>
|
||||
internal bool ProcessButton(X11.XButtonEvent e)
|
||||
internal bool ProcessButton(ref X11.XButtonEvent e)
|
||||
{
|
||||
Mouse m = mice[0];
|
||||
bool pressed = e.type == XEventName.ButtonPress;
|
||||
|
@ -69,7 +69,7 @@ namespace OpenTK.Platform.X11
|
|||
/// </summary>
|
||||
/// <param name="e">The X11.XMotionEvent to process.</param>
|
||||
/// <returns>True if the event was processed, false otherwise.</returns>
|
||||
internal bool ProcessMotion(X11.XMotionEvent e)
|
||||
internal bool ProcessMotion(ref X11.XMotionEvent e)
|
||||
{
|
||||
Mouse m = mice[0];
|
||||
m.X = e.x;
|
||||
|
|
Loading…
Reference in a new issue