private unsafe static void ProcessRawMotion(XIMouse d, ref XIRawEvent raw) { // Note: we use the raw values here, without pointer // ballistics and any other modification. double x = 0; double y = 0; double h = 0; double v = 0; if (d.MotionX.number != -1) { x = ReadRawValue(ref raw, d.MotionX.number); } if (d.MotionY.number != -1) { y = ReadRawValue(ref raw, d.MotionY.number); } if (d.ScrollX.number != -1) { h = ReadRawValue(ref raw, d.ScrollX.number) / d.ScrollX.increment; } if (d.ScrollY.number != -1) { v = ReadRawValue(ref raw, d.ScrollY.number) / d.ScrollY.increment; } if (d.MotionX.mode == XIMode.Relative) { d.State.X += (int)Math.Round(x); } else { d.State.X = (int)Math.Round(x); } if (d.MotionY.mode == XIMode.Relative) { d.State.Y += (int)Math.Round(y); } else { d.State.Y = (int)Math.Round(y); } // Note: osuTK follows the windows scrolling convention where // (+h, +v) = (right, up). XI2 uses (+h, +v) = (right, down) // instead, so we need to flip the vertical offset. d.State.SetScrollRelative((float)h, (float)(-v)); }
private void ProcessRawEvent(ref XGenericEventCookie cookie) { lock (Sync) { unsafe { XIRawEvent raw = *(XIRawEvent *)cookie.data; XIMouse mouse; XIKeyboard keyboard; switch (raw.evtype) { case XIEventType.RawMotion: if (GetMouseDevice(raw.deviceid, out mouse)) { ProcessRawMotion(mouse, ref raw); } break; case XIEventType.RawButtonPress: case XIEventType.RawButtonRelease: if (GetMouseDevice(raw.deviceid, out mouse)) { float dx, dy; MouseButton button = X11KeyMap.TranslateButton(raw.detail, out dx, out dy); mouse.State[button] = raw.evtype == XIEventType.RawButtonPress; if (mouse.ScrollX.number == -1 && mouse.ScrollY.number == -1) { mouse.State.SetScrollRelative(dx, dy); } } break; case XIEventType.RawKeyPress: case XIEventType.RawKeyRelease: if (GetKeyboardDevice(raw.deviceid, out keyboard)) { Key key; if (KeyMap.TranslateKey(raw.detail, out key)) { keyboard.State[key] = raw.evtype == XIEventType.RawKeyPress; } } break; } } } }
private unsafe static double ReadRawValue(ref XIRawEvent raw, int bit) { double value = 0; if (IsBitSet(raw.valuators.mask, bit)) { // Find the offset where this value is stored. // The offset is equal to the number of bits // set in raw.valuators.mask between [0, bit) int offset = 0; for (int i = 0; i < bit; i++) { if (IsBitSet(raw.valuators.mask, i)) { offset++; } } value = *((double *)raw.raw_values + offset); } return(value); }