using System; using System.Collections.Generic; using System.Text; using OpenTK.Input; using System.Diagnostics; namespace OpenTK.Platform.X11 { /// /// Drives the InputDriver on X11. /// This class supports OpenTK, and is not intended for users of OpenTK. /// internal sealed class X11Input : IInputDriver { private X11Keyboard keyboardDriver; private WindowInfo window; XEvent e = new XEvent(); #region --- Constructors --- /// /// Constructs a new X11Input driver. Creates a hidden InputOnly window, child to /// the main application window, which selects input events and routes them to /// the device specific drivers (Keyboard, Mouse, Hid). /// /// public X11Input(WindowInfo parent) { Debug.WriteLine("Initalizing X11 input driver."); Debug.Indent(); if (parent == null) { throw new ArgumentException("A valid parent window must be defined, in order to create an X11Input driver."); } /* Debug.WriteLine("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 ); if (window.Handle == IntPtr.Zero) { throw new Exception("Could not create 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 + ")"); // Select input events to be reported here. //API.SelectInput(window.Display, window.Parent.Handle, // EventMask.KeyReleaseMask | EventMask.KeyPressMask); keyboardDriver = new X11Keyboard(window); */ window = new WindowInfo(parent); keyboardDriver = new X11Keyboard(parent); API.SelectInput(parent.Display, parent.Handle, EventMask.KeyReleaseMask | EventMask.KeyPressMask); Debug.Unindent(); } #endregion #region --- IInputDriver Members --- #region public IList InputDevices public IList InputDevices { get { throw new Exception("The method or operation is not implemented."); } } #endregion #region public IList Keyboard public IList Keyboard { get { return keyboardDriver.Keyboard; } } #endregion #region public IList Mouse public IList Mouse { get { throw new Exception("The method or operation is not implemented."); } } #endregion /// /// Consumes to keyboard, mouse, etc events, routing them to their /// respective drivers. /// public void ProcessEvents() { while (API.CheckMaskEvent(window.Display, EventMask.KeyReleaseMask | EventMask.KeyPressMask, ref e)) { Debug.Print("Input window received {0} event... ", e.type.ToString()); keyboardDriver.ProcessKeyboardEvent(e.KeyEvent); } /* try { while (API.CheckIfEvent(window.Display, ref e, check, IntPtr.Zero)) { Debug.Print("Input window received {0} event... ", e.type.ToString()); keyboardDriver.ProcessKeyboardEvent(e.KeyEvent); } } catch (Exception e) { Debug.Print("DANGER: Possible callback exception: {0}", e.ToString()); } */ } API.CheckEventPredicate check = KeyEventPredicate; private static bool KeyEventPredicate(IntPtr display, ref XEvent @event, IntPtr arg) { bool ret = false; try { ret = (@event.type == XEventName.KeyRelease || @event.type == XEventName.KeyPress); } catch (Exception e) { Debug.Print("DANGER: Exception caught during unmanaged callback: {0}", e.ToString()); } return ret; } #endregion } }