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
|
// Legacy input support
|
||||||
X11Input driver;
|
X11Input driver;
|
||||||
|
KeyboardDevice keyboard;
|
||||||
MouseDevice mouse;
|
MouseDevice mouse;
|
||||||
|
|
||||||
// Window manager hints for fullscreen windows.
|
// Window manager hints for fullscreen windows.
|
||||||
|
@ -119,6 +120,8 @@ namespace OpenTK.Platform.X11
|
||||||
readonly byte[] ascii = new byte[16];
|
readonly byte[] ascii = new byte[16];
|
||||||
readonly char[] chars = new char[16];
|
readonly char[] chars = new char[16];
|
||||||
readonly KeyPressEventArgs KPEventArgs = new KeyPressEventArgs('\0');
|
readonly KeyPressEventArgs KPEventArgs = new KeyPressEventArgs('\0');
|
||||||
|
readonly KeyboardKeyEventArgs KeyDownEventArgs = new KeyboardKeyEventArgs();
|
||||||
|
readonly KeyboardKeyEventArgs KeyUpEventArgs = new KeyboardKeyEventArgs();
|
||||||
|
|
||||||
readonly IntPtr EmptyCursor;
|
readonly IntPtr EmptyCursor;
|
||||||
|
|
||||||
|
@ -209,6 +212,7 @@ namespace OpenTK.Platform.X11
|
||||||
RefreshWindowBounds(ref e);
|
RefreshWindowBounds(ref e);
|
||||||
|
|
||||||
driver = new X11Input(window);
|
driver = new X11Input(window);
|
||||||
|
keyboard = driver.Keyboard[0];
|
||||||
mouse = driver.Mouse[0];
|
mouse = driver.Mouse[0];
|
||||||
|
|
||||||
EmptyCursor = CreateEmptyCursor(window);
|
EmptyCursor = CreateEmptyCursor(window);
|
||||||
|
@ -795,32 +799,50 @@ namespace OpenTK.Platform.X11
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XEventName.KeyPress:
|
case XEventName.KeyPress:
|
||||||
driver.ProcessEvent(ref e);
|
case XEventName.KeyRelease:
|
||||||
int status = 0;
|
bool pressed = e.type == XEventName.KeyPress;
|
||||||
status = Functions.XLookupString(ref e.KeyEvent, ascii, ascii.Length, null, IntPtr.Zero);
|
Key key;
|
||||||
Encoding.Default.GetChars(ascii, 0, status, chars, 0);
|
if (driver.TranslateKey(ref e.KeyEvent, out key))
|
||||||
|
|
||||||
EventHandler<KeyPressEventArgs> key_press = KeyPress;
|
|
||||||
if (key_press != null)
|
|
||||||
{
|
{
|
||||||
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];
|
if (!Char.IsControl(chars[i]))
|
||||||
key_press(this, KPEventArgs);
|
{
|
||||||
|
KPEventArgs.KeyChar = chars[i];
|
||||||
|
KeyPress(this, KPEventArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case XEventName.MotionNotify:
|
||||||
{
|
{
|
||||||
// Try to detect and ignore events from XWarpPointer, below.
|
// Try to detect and ignore events from XWarpPointer, below.
|
||||||
|
|
|
@ -148,29 +148,38 @@ namespace OpenTK.Platform.X11
|
||||||
#endif
|
#endif
|
||||||
#endregion
|
#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)
|
#region internal void ProcessEvent(ref XEvent e)
|
||||||
|
|
||||||
internal void ProcessEvent(ref XEvent e)
|
internal void ProcessEvent(ref XEvent e)
|
||||||
{
|
{
|
||||||
switch (e.type)
|
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:
|
case XEventName.ButtonPress:
|
||||||
if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true;
|
if (e.ButtonEvent.button == 1) mouse[OpenTK.Input.MouseButton.Left] = true;
|
||||||
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = true;
|
else if (e.ButtonEvent.button == 2) mouse[OpenTK.Input.MouseButton.Middle] = true;
|
||||||
|
|
Loading…
Reference in a new issue