private void SdlRunLoop() { Sdl.Event ev; while (Sdl.PollEvent(out ev) == 1) { if (ev.Type == Sdl.EventType.Quit) { _isExiting++; } else if (ev.Type == Sdl.EventType.JoyDeviceAdded) { Joystick.AddDevice(ev.JoystickDevice.Which); } else if (ev.Type == Sdl.EventType.ControllerDeviceRemoved) { GamePad.RemoveDevice(ev.ControllerDevice.Which); } else if (ev.Type == Sdl.EventType.JoyDeviceRemoved) { Joystick.RemoveDevice(ev.JoystickDevice.Which); } else if (ev.Type == Sdl.EventType.MouseWheel) { const int wheelDelta = 120; Mouse.ScrollY += ev.Wheel.Y * wheelDelta; Mouse.ScrollX += ev.Wheel.X * wheelDelta; } else if (ev.Type == Sdl.EventType.MouseMotion) { Window.MouseState.X = ev.Motion.X; Window.MouseState.Y = ev.Motion.Y; } else if (ev.Type == Sdl.EventType.KeyDown) { var key = KeyboardUtil.ToXna(ev.Key.Keysym.Sym); if (!_keys.Contains(key)) { _keys.Add(key); } char character = (char)ev.Key.Keysym.Sym; if (char.IsControl(character)) { _view.CallTextInput(character, key); } } else if (ev.Type == Sdl.EventType.KeyUp) { var key = KeyboardUtil.ToXna(ev.Key.Keysym.Sym); _keys.Remove(key); } else if (ev.Type == Sdl.EventType.TextInput) { int len = 0; string text = String.Empty; unsafe { while (Marshal.ReadByte((IntPtr)ev.Text.Text, len) != 0) { len++; } var buffer = new byte[len]; Marshal.Copy((IntPtr)ev.Text.Text, buffer, 0, len); text = System.Text.Encoding.UTF8.GetString(buffer); } if (text.Length == 0) { continue; } foreach (var c in text) { var key = KeyboardUtil.ToXna((int)c); _view.CallTextInput(c, key); } } else if (ev.Type == Sdl.EventType.DropFile) { _view.CallFileDrop(Sdl.GetString(ev.Drop.File)); } else if (ev.Type == Sdl.EventType.WindowEvent) { if (ev.Window.WindowID == _view.Id) { if (ev.Window.EventID == Sdl.Window.EventId.Resized || ev.Window.EventID == Sdl.Window.EventId.SizeChanged) { _view.ClientResize(ev.Window.Data1, ev.Window.Data2); } else if (ev.Window.EventID == Sdl.Window.EventId.FocusGained) { IsActive = true; } else if (ev.Window.EventID == Sdl.Window.EventId.FocusLost) { IsActive = false; } else if (ev.Window.EventID == Sdl.Window.EventId.Moved) { _view.Moved(); } else if (ev.Window.EventID == Sdl.Window.EventId.Close) { _isExiting++; } } } } }
private void SdlRunLoop() { Sdl.Event ev; while (Sdl.PollEvent(out ev) == 1) { if (ev.Type == Sdl.EventType.Quit) { _isExiting++; } else if (ev.Type == Sdl.EventType.JoyDeviceAdded) { Joystick.AddDevice(ev.JoystickDevice.Which); } else if (ev.Type == Sdl.EventType.ControllerDeviceRemoved) { GamePad.RemoveDevice(ev.ControllerDevice.Which); } else if (ev.Type == Sdl.EventType.JoyDeviceRemoved) { Joystick.RemoveDevice(ev.JoystickDevice.Which); } else if (ev.Type == Sdl.EventType.MouseWheel) { const int wheelDelta = 120; Mouse.ScrollY += ev.Wheel.Y * wheelDelta; Mouse.ScrollX += ev.Wheel.X * wheelDelta; } else if (ev.Type == Sdl.EventType.MouseMotion) { Window.MouseState.X = ev.Motion.X; Window.MouseState.Y = ev.Motion.Y; } else if (ev.Type == Sdl.EventType.KeyDown) { var key = KeyboardUtil.ToXna(ev.Key.Keysym.Sym); if (!_keys.Contains(key)) { _keys.Add(key); } char character = (char)ev.Key.Keysym.Sym; if (char.IsControl(character)) { _view.CallTextInput(character, key); } } else if (ev.Type == Sdl.EventType.KeyUp) { var key = KeyboardUtil.ToXna(ev.Key.Keysym.Sym); _keys.Remove(key); } else if (ev.Type == Sdl.EventType.TextInput) { if (_view.IsTextInputHandled) { int len = 0; int utf8character = 0; // using an int to encode multibyte characters longer than 2 bytes byte currentByte = 0; int charByteSize = 0; // UTF8 char lenght to decode int remainingShift = 0; unsafe { while ((currentByte = Marshal.ReadByte((IntPtr)ev.Text.Text, len)) != 0) { // we're reading the first UTF8 byte, we need to check if it's multibyte if (charByteSize == 0) { if (currentByte < 192) { charByteSize = 1; } else if (currentByte < 224) { charByteSize = 2; } else if (currentByte < 240) { charByteSize = 3; } else { charByteSize = 4; } utf8character = 0; remainingShift = 4; } // assembling the character utf8character <<= 8; utf8character |= currentByte; charByteSize--; remainingShift--; if (charByteSize == 0) // finished decoding the current character { utf8character <<= remainingShift * 8; // shifting it to full UTF8 scope // SDL returns UTF8-encoded characters while C# char type is UTF16-encoded (and limited to the 0-FFFF range / does not support surrogate pairs) // so we need to convert it to Unicode codepoint and check if it's within the supported range int codepoint = UTF8ToUnicode(utf8character); if (codepoint >= 0 && codepoint < 0xFFFF) { var key = KeyboardUtil.ToXna(codepoint); _view.CallTextInput((char)codepoint, key); } // UTF16 characters beyond 0xFFFF are not supported (and would require a surrogate encoding that is not supported by the char type) } len++; } } } } else if (ev.Type == Sdl.EventType.WindowEvent) { if (ev.Window.WindowID == _view.Id) { if (ev.Window.EventID == Sdl.Window.EventId.Resized || ev.Window.EventID == Sdl.Window.EventId.SizeChanged) { _view.ClientResize(ev.Window.Data1, ev.Window.Data2); } else if (ev.Window.EventID == Sdl.Window.EventId.FocusGained) { IsActive = true; } else if (ev.Window.EventID == Sdl.Window.EventId.FocusLost) { IsActive = false; } else if (ev.Window.EventID == Sdl.Window.EventId.Moved) { _view.Moved(); } else if (ev.Window.EventID == Sdl.Window.EventId.Close) { _isExiting++; } } } } }