Implemented X11 KeyDown/KeyUp events and reduced code duplication
This commit is contained in:
parent
ffdf881cea
commit
4d27b6ee55
2 changed files with 67 additions and 36 deletions
|
@ -59,6 +59,7 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
// Legacy input support
|
||||
X11Input driver;
|
||||
KeyboardDevice keyboard;
|
||||
MouseDevice mouse;
|
||||
|
||||
// Window manager hints for fullscreen windows.
|
||||
|
@ -119,6 +120,8 @@ namespace OpenTK.Platform.X11
|
|||
readonly byte[] ascii = new byte[16];
|
||||
readonly char[] chars = new char[16];
|
||||
readonly KeyPressEventArgs KPEventArgs = new KeyPressEventArgs('\0');
|
||||
readonly KeyboardKeyEventArgs KeyDownEventArgs = new KeyboardKeyEventArgs();
|
||||
readonly KeyboardKeyEventArgs KeyUpEventArgs = new KeyboardKeyEventArgs();
|
||||
|
||||
readonly IntPtr EmptyCursor;
|
||||
|
||||
|
@ -209,6 +212,7 @@ namespace OpenTK.Platform.X11
|
|||
RefreshWindowBounds(ref e);
|
||||
|
||||
driver = new X11Input(window);
|
||||
keyboard = driver.Keyboard[0];
|
||||
mouse = driver.Mouse[0];
|
||||
|
||||
EmptyCursor = CreateEmptyCursor(window);
|
||||
|
@ -256,7 +260,7 @@ namespace OpenTK.Platform.X11
|
|||
#endregion
|
||||
|
||||
#region Private Members
|
||||
|
||||
|
||||
#region private void RegisterAtoms()
|
||||
|
||||
/// <summary>
|
||||
|
@ -795,32 +799,50 @@ namespace OpenTK.Platform.X11
|
|||
break;
|
||||
|
||||
case XEventName.KeyPress:
|
||||
driver.ProcessEvent(ref e);
|
||||
int status = 0;
|
||||
status = Functions.XLookupString(ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero);
|
||||
Encoding.Default.GetChars(ascii, 0, status, chars, 0);
|
||||
|
||||
EventHandler<KeyPressEventArgs> key_press = KeyPress;
|
||||
if (key_press != null)
|
||||
case XEventName.KeyRelease:
|
||||
bool pressed = e.type == XEventName.KeyPress;
|
||||
Key key;
|
||||
if (driver.TranslateKey(ref e.KeyEvent, out key))
|
||||
{
|
||||
for (int i = 0; i < status; i++)
|
||||
if (pressed)
|
||||
{
|
||||
if (!Char.IsControl(chars[i]))
|
||||
// Raise KeyDown event
|
||||
KeyDownEventArgs.Key = key;
|
||||
KeyDownEventArgs.ScanCode = (uint)e.KeyEvent.keycode;
|
||||
KeyDown(this, KeyDownEventArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Raise KeyUp event
|
||||
KeyUpEventArgs.Key = key;
|
||||
KeyUpEventArgs.ScanCode = (uint)e.KeyEvent.keycode;
|
||||
KeyUp(this, KeyDownEventArgs);
|
||||
}
|
||||
|
||||
// Update legacy GameWindow.Keyboard API:
|
||||
keyboard.SetKey(key, (uint)e.KeyEvent.keycode, pressed);
|
||||
|
||||
if (pressed)
|
||||
{
|
||||
// Translate XKeyPress to characters and
|
||||
// raise KeyPress events
|
||||
int status = 0;
|
||||
status = Functions.XLookupString(
|
||||
ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero);
|
||||
Encoding.Default.GetChars(ascii, 0, status, chars, 0);
|
||||
|
||||
for (int i = 0; i < status; i++)
|
||||
{
|
||||
KPEventArgs.KeyChar = chars[i];
|
||||
key_press(this, KPEventArgs);
|
||||
if (!Char.IsControl(chars[i]))
|
||||
{
|
||||
KPEventArgs.KeyChar = chars[i];
|
||||
KeyPress(this, KPEventArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case XEventName.KeyRelease:
|
||||
// Todo: raise KeyPress event. Use code from
|
||||
// http://anonsvn.mono-project.com/viewvc/trunk/mcs/class/Managed.Windows.Forms/System.Windows.Forms/X11Keyboard.cs?view=markup
|
||||
|
||||
driver.ProcessEvent(ref e);
|
||||
break;
|
||||
|
||||
case XEventName.MotionNotify:
|
||||
{
|
||||
// Try to detect and ignore events from XWarpPointer, below.
|
||||
|
|
|
@ -148,29 +148,38 @@ namespace OpenTK.Platform.X11
|
|||
#endif
|
||||
#endregion
|
||||
|
||||
#region TranslateKey
|
||||
|
||||
internal bool TranslateKey(ref XKeyEvent e, out Key key)
|
||||
{
|
||||
XKey keysym = (XKey)API.LookupKeysym(ref e, 0);
|
||||
XKey keysym2 = (XKey)API.LookupKeysym(ref e, 1);
|
||||
key = Key.Unknown;
|
||||
|
||||
if (keymap.ContainsKey(keysym))
|
||||
{
|
||||
key = keymap[keysym];
|
||||
}
|
||||
else if (keymap.ContainsKey(keysym2))
|
||||
{
|
||||
key = keymap[keysym2];
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.keycode, (XKey)keysym, (XKey)keysym2);
|
||||
}
|
||||
|
||||
return key != Key.Unknown;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal void ProcessEvent(ref XEvent e)
|
||||
|
||||
internal void ProcessEvent(ref XEvent e)
|
||||
{
|
||||
switch (e.type)
|
||||
{
|
||||
case XEventName.KeyPress:
|
||||
case XEventName.KeyRelease:
|
||||
bool pressed = e.type == XEventName.KeyPress;
|
||||
XKey keysym = (XKey)API.LookupKeysym(ref e.KeyEvent, 0);
|
||||
XKey keysym2 = (XKey)API.LookupKeysym(ref e.KeyEvent, 1);
|
||||
Key key = Key.Unknown;
|
||||
|
||||
if (keymap.ContainsKey(keysym))
|
||||
key = keymap[keysym];
|
||||
else if (keymap.ContainsKey(keysym2))
|
||||
key = keymap[keysym2];
|
||||
else
|
||||
Debug.Print("KeyCode {0} (Keysym: {1}, {2}) not mapped.", e.KeyEvent.keycode, (XKey)keysym, (XKey)keysym2);
|
||||
|
||||
keyboard.SetKey(key, (uint)e.KeyEvent.keycode, pressed);
|
||||
break;
|
||||
|
||||
case XEventName.ButtonPress:
|
||||
if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true;
|
||||
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = true;
|
||||
|
|
Loading…
Reference in a new issue