protected override void Initialize() { if (_display != IntPtr.Zero) { LibX11.XCloseDisplay(_display); } _display = IntPtr.Zero; _display = LibX11.XOpenDisplay(IntPtr.Zero); if (_display == IntPtr.Zero) { throw new Exception("Could not open display."); } if (LibX11.XSelectInput(_display, _window, LibX11.KeyPressMask | LibX11.KeyReleaseMask) == LibX11.BadWindow) { throw new Exception("X Error!"); } if (_grabKeyboard) { LibX11.XGrabKeyboard(_display, _window, true, LibX11.GrabModeAsync, LibX11.GrabModeAsync, LibX11.CurrentTime); } _keyFocusLost = false; }
public override string AsString(KeyCode key) { var pair = keyConversion.FirstOrDefault((item) => { return(item.Value == key); }); string keyCodeString; keyCodeString = LibX11.XKeysymToString(pair.Key); return(keyCodeString == null ? "Unknown" : keyCodeString); }
private void hide(bool hidePointer) { if (hidePointer) { LibX11.XDefineCursor(_display, _window, _cursor); } else { LibX11.XUndefineCursor(_display, _window); } }
private void grab(bool grabPointer) { if (grabPointer) { LibX11.XGrabPointer(_display, _window, true, 0, LibX11.GrabModeAsync, LibX11.GrabModeAsync, _window, IntPtr.Zero, LibX11.CurrentTime); } else { LibX11.XUngrabPointer(_display, LibX11.CurrentTime); } }
protected override void Dispose(bool disposeManagedResources) { if (_display != IntPtr.Zero) { if (_grabKeyboard) { LibX11.XUngrabKeyboard(_display, LibX11.CurrentTime); } LibX11.XCloseDisplay(_display); } base.Dispose(disposeManagedResources); }
// Detects the underlying OS and runtime. static Environment() { try { // Distinguish between Linux, Mac OS X and other Unix operating systems. string kernel_name = (new UnixKernel()).SysName; switch (kernel_name) { case null: case "": throw new PlatformNotSupportedException("Unknown platform."); case "Linux": _RunningOnLinux = _RunningOnUnix = true; break; case "Darwin": _RunningOnMacOS = _RunningOnUnix = true; break; default: _RunningOnUnix = true; break; } } finally { _RunningOnWindows = true; } // Detect whether X is present. // Hack: it seems that this check will cause X to initialize itself on Mac OS X Leopard and newer. // We don't want that (we'll be using the native interfaces anyway), so we'll avoid this check // when we detect Mac OS X. if (!RunningOnMacOS) { try { _RunningOnX11 = LibX11.XOpenDisplay(IntPtr.Zero) != IntPtr.Zero; } catch { } } // Detect the Mono runtime (code adapted from http://mono.wikia.com/wiki/Detecting_if_program_is_running_in_Mono). _RunningOnMono = Type.GetType("Mono.Runtime") != null; log.Debug(m => m("Detected Runtime Environment : {0} / {1}", RunningOnWindows ? "Windows" : RunningOnLinux ? "Linux" : RunningOnMacOS ? "MacOS" : RunningOnUnix ? "Unix" : RunningOnX11 ? "X11" : "Unknown Platform", RunningOnMono ? "Mono" : ".Net")); }
protected override void Initialize() { MouseState = new MouseState(); _moved = false; _warped = false; _lastMouseX = _lastMouseY = 6; if (_display != IntPtr.Zero) { LibX11.XCloseDisplay(_display); } _display = IntPtr.Zero; _display = LibX11.XOpenDisplay(IntPtr.Zero); if (_display == IntPtr.Zero) { throw new Exception("X11Mouse.Initialize, can not open display"); } //var sir = LibX11.XSelectInput( _display, _window, LibX11.ButtonPressMask | LibX11.ButtonReleaseMask | LibX11.PointerMotionMask ); //if ( sir == LibX11.BadWindow ) // throw new Exception( "X11Mouse.Initialize, X Error!" ); //Warp mouse inside window LibX11.XWarpPointer(_display, IntPtr.Zero, _window, 0, 0, 0, 0, 6, 6); //TODO: Create a blank cursor IntPtr bm_no; LibX11.XColor black = new LibX11.XColor(), dummy = new LibX11.XColor(); IntPtr colormap; byte[] no_data = { 0, 0, 0, 0, 0, 0, 0, 0 }; colormap = LibX11.XDefaultColormap(_display, LibX11.XDefaultScreen(_display)); LibX11.XAllocNamedColor(_display, colormap, "black", ref black, ref dummy); bm_no = LibX11.XCreateBitmapFromData(_display, _window, no_data, 8, 8); _cursor = LibX11.XCreatePixmapCursor(_display, bm_no, bm_no, ref black, ref black, 0, 0); grab(grabMouse); hide(hideMouse); mouseFocusLost = false; }
/// <summary> /// /// </summary> public override void Capture() { int key; X11InputManager linMan = (X11InputManager)Creator; System.Diagnostics.Debug.Assert(linMan != null); while (LibX11.XPending(_display) > 0) { /*if ( LibX11.XCheckMaskEvent( _display, (int)(LibX11.XEventName.KeyPress | LibX11.XEventName.KeyRelease), ref xevent ) == true )*/ LibX11.XNextEvent(_display, ref _xEvent); { switch (_xEvent.type) { case LibX11.XEventName.KeyPress: int character = 0; if (TextMode != TextTranslationMode.Off) { StringBuilder sb = new StringBuilder(6); LibX11.XLookupString(ref _xEvent.KeyEvent, sb, 6, out key, IntPtr.Zero); if (TextMode == TextTranslationMode.Unicode) { character = UTF8toUTF32(sb); } else if (TextMode == TextTranslationMode.Ascii) { character = (int)sb[0]; } } //Mask out the modifier states X11 sets and read again _xEvent.KeyEvent.state &= ~LibX11.ShiftMask; _xEvent.KeyEvent.state &= ~LibX11.LockMask; StringBuilder b = new StringBuilder(); LibX11.XLookupString(ref _xEvent.KeyEvent, b, 0, out key, IntPtr.Zero); injectKeyDown(key, character); //Check for Alt-Tab if ((_xEvent.KeyEvent.state & LibX11.Mod1Mask) != 0 && key == (int)LibX11.KeySym.XK_Tab) { linMan.GrabState = false; } break; case LibX11.XEventName.KeyRelease: if (!IsKeyRepeat(_xEvent)) { //Mask out the modifier states X sets.. or we will get improper values _xEvent.KeyEvent.state &= ~LibX11.ShiftMask; _xEvent.KeyEvent.state &= ~LibX11.LockMask; StringBuilder sb = new StringBuilder(6); LibX11.XLookupString(ref _xEvent.KeyEvent, sb, 0, out key, IntPtr.Zero); injectKeyUp(key); } break; } } } //end while //If grabbing mode is on.. Handle focus lost/gained via Alt-Tab and mouse clicks if (_grabKeyboard) { System.Diagnostics.Debug.Assert(linMan != null); if (linMan.GrabState == false) { // are no longer grabbing if (_keyFocusLost == false) { // ungrab keyboard LibX11.XUngrabKeyboard(_display, LibX11.CurrentTime); _keyFocusLost = true; } } else { // We are grabbing - and regained focus if (_keyFocusLost == true) { // regrab keyboard LibX11.XGrabKeyboard(_display, _window, true, LibX11.GrabModeAsync, LibX11.GrabModeAsync, LibX11.CurrentTime); _keyFocusLost = false; } } } }
private void processXEvents() { IntPtr rootWindow, childWindow; int root_x, root_y, win_x, win_y; uint mask; bool doMove = true; LibX11.XQueryPointer(_display, _window, out rootWindow, out childWindow, out root_x, out root_y, out win_x, out win_y, out mask); int sysX = win_x; int sysY = win_y; if (_warped) { if (sysX < 5 || sysX > MouseState.Width - 5 || sysY < 5 || sysY > MouseState.Height - 5) { doMove = false; } } if (doMove) { int dx = sysX - _lastMouseX; int dy = sysY - _lastMouseY; _lastMouseX = sysX; _lastMouseY = sysY; MouseState.X.Absolute += dx; MouseState.Y.Absolute += dy; MouseState.X.Relative += dx; MouseState.Y.Relative += dy; if (grabMouse) { if (MouseState.X.Absolute < 0) { MouseState.X.Absolute = 0; } else if (MouseState.X.Absolute > MouseState.Width) { MouseState.X.Absolute = MouseState.Width; } if (MouseState.Y.Absolute < 0) { MouseState.Y.Absolute = 0; } else if (MouseState.Y.Absolute > MouseState.Height) { MouseState.Y.Absolute = MouseState.Height; } if (mouseFocusLost == true) { if (sysX < 5 || sysX > MouseState.Width - 5 || sysY < 5 || sysY > MouseState.Height - 5) { _lastMouseX = MouseState.Width >> 1; _lastMouseY = MouseState.Height >> 1; LibX11.XWarpPointer(_display, IntPtr.Zero, _window, 0, 0, 0, 0, _lastMouseX, _lastMouseY); _warped = true; } } } if (dx + dy != 0) { _moved = true; } } var anyButtons = ((int)LibX11.Buttons.Button1Mask | (int)LibX11.Buttons.Button2Mask | (int)LibX11.Buttons.Button3Mask | (int)LibX11.Buttons.Button4Mask | (int)LibX11.Buttons.Button5Mask); if (lastButtons != (mask & (int)anyButtons)) { (new List <int> () { (int)LibX11.Buttons.Button1Mask, (int)LibX11.Buttons.Button2Mask, (int)LibX11.Buttons.Button3Mask }).ForEach((button) => { var mb = ToMouseButton(button); if (((lastButtons & (int)button) == 0) && (((mask & (int)anyButtons) & (int)button) != 0)) { MouseState.Buttons |= (int)mb; log.InfoFormat("ButtonPressed : {0}", button); if (IsBuffered == true && EventListener != null) { if (EventListener.MousePressed(new MouseEventArgs(this, MouseState), mb) == false) { return; } } } if (((lastButtons & (int)button) != 0) && (((mask & (int)anyButtons) & (int)button) == 0)) { MouseState.Buttons &= ~(int)mb; log.InfoFormat("ButtonReleased : {0}", button); if (IsBuffered == true && EventListener != null) { if (EventListener.MouseReleased(new MouseEventArgs(this, MouseState), mb) == false) { return; } } } }); lastButtons = (int)(mask & (int)anyButtons); } //The Z axis gets pushed/released pair message (this is up) if ((mask & (int)LibX11.Buttons.Button4Mask) != 0) { log.InfoFormat("MouseWheel : Up"); MouseState.Z.Relative += 120; MouseState.Z.Absolute += 120; _moved = true; } //The Z axis gets pushed/released pair message (this is down) if ((mask & (int)LibX11.Buttons.Button5Mask) != 0) { log.InfoFormat("MouseWheel : Down"); MouseState.Z.Relative -= 120; MouseState.Z.Absolute -= 120; _moved = true; } /* * // this algorithm requires the ButtonPressMask be specifiec * // in the XSelectEvent call during Initialize. X11 Documentation * // http://tronche.com/gui/x/xlib/event-handling/XSelectInput.html * // states that only *one* client may request this mask. * // Since SWF and the OpenTK GameWindow classes both request this * // This can't be used with those X11 form types. * while ( LibX11.XPending( _display ) > 0 ) * { * log.InfoFormat( "Found Pending Events..." ); * LibX11.XNextEvent( _display, ref _xEvent ); * MouseButtonID mb = MouseButtonID.Button3; * * log.InfoFormat( "Event.Type : {0}", _xEvent.type ); * switch ( _xEvent.type ) * { * case LibX11.XEventName.MotionNotify: * * int sysX = _xEvent.MotionEvent.x; * int sysY = _xEvent.MotionEvent.y; * * if ( _warped ) * { * if ( sysX < 5 || sysX > MouseState.Width - 5 || * sysY < 5 || sysY > MouseState.Height - 5 ) * continue; * } * int dx = sysX - _lastMouseX; * int dy = sysY - _lastMouseY; * _lastMouseX = sysX; * _lastMouseY = sysY; * MouseState.X.Absolute += dx; * MouseState.Y.Absolute += dy; * MouseState.X.Relative += dx; * MouseState.Y.Relative += dy; * * if ( grabMouse ) * { * if ( MouseState.X.Absolute < 0 ) * MouseState.X.Absolute = 0; * else if ( MouseState.X.Absolute > MouseState.Width ) * MouseState.X.Absolute = MouseState.Width; * if ( MouseState.Y.Absolute < 0 ) * MouseState.Y.Absolute = 0; * else if ( MouseState.Y.Absolute > MouseState.Height ) * MouseState.Y.Absolute = MouseState.Height; * * if ( mouseFocusLost == true ) * { * if ( sysX < 5 || sysX > MouseState.Width - 5 || * sysY < 5 || sysY > MouseState.Height - 5 ) * { * _lastMouseX = MouseState.Width >> 1; * _lastMouseY = MouseState.Height >> 1; * LibX11.XWarpPointer( _display, IntPtr.Zero, _window, 0, 0, 0, 0, _lastMouseX, _lastMouseY ); * _warped = true; * } * } * } * _moved = true; * break; * * case LibX11.XEventName.ButtonPress: * mb = ToMouseButton( _xEvent.ButtonEvent.button ); * MouseState.Buttons |= (int)mb; * * ((X11InputManager)Creator).GrabState = true; * * if ( _xEvent.ButtonEvent.button < 4 ) * { * if ( IsBuffered == true && EventListener != null ) * if ( EventListener.MousePressed( new MouseEventArgs( this, MouseState ), mb ) == false ) * return; * } * break; * case LibX11.XEventName.ButtonRelease: * mb = ToMouseButton( _xEvent.ButtonEvent.button ); * MouseState.Buttons &= ~(int)mb; * if ( _xEvent.ButtonEvent.button < 4 ) * { * if ( IsBuffered == true && EventListener != null ) * if ( EventListener.MouseReleased( new MouseEventArgs( this, MouseState ), mb ) == false ) * return; * } * //The Z axis gets pushed/released pair message (this is up) * else if( _xEvent.ButtonEvent.button == 4 ) * { * MouseState.Z.Relative += 120; * MouseState.Z.Absolute += 120; * _moved = true; * } * //The Z axis gets pushed/released pair message (this is down) * else if( _xEvent.ButtonEvent.button == 5 ) * { * MouseState.Z.Relative -= 120; * MouseState.Z.Absolute -= 120; * _moved = true; * } * break; * } * } */ }