diff --git a/Source/OpenTK/Platform/X11/Functions.cs b/Source/OpenTK/Platform/X11/Functions.cs index f24224ab..6611e032 100644 --- a/Source/OpenTK/Platform/X11/Functions.cs +++ b/Source/OpenTK/Platform/X11/Functions.cs @@ -479,6 +479,13 @@ namespace OpenTK.Platform.X11 public static extern void XPutImage(Display display, IntPtr drawable, IntPtr gc, IntPtr image, int src_x, int src_y, int dest_x, int dest_y, uint width, uint height); + [DllImport("libX11")] + public static extern int XLookupString(ref XKeyEvent event_struct, [Out] byte[] buffer_return, + int bytes_buffer, [Out] KeySym[] keysym_return, IntPtr status_in_out); + + [DllImport("libX11")] + public static extern int XRefreshKeyboardMapping(ref XMappingEvent event_map); + static readonly IntPtr CopyFromParent = IntPtr.Zero; public static void SendNetWMMessage(X11WindowInfo window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2) diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs index 887f0eed..5976246c 100644 --- a/Source/OpenTK/Platform/X11/X11GLNative.cs +++ b/Source/OpenTK/Platform/X11/X11GLNative.cs @@ -103,8 +103,11 @@ namespace OpenTK.Platform.X11 bool exists; bool isExiting; - bool _decorations_hidden = false; - + bool _decorations_hidden = false; + + readonly byte[] characters = new byte[16]; // Keyboard input + readonly KeyPressEventArgs KPEventArgs = new KeyPressEventArgs('\0'); + #endregion #region Constructors @@ -140,7 +143,7 @@ namespace OpenTK.Platform.X11 attributes.border_pixel = IntPtr.Zero; attributes.colormap = Functions.XCreateColormap(window.Display, window.RootWindow, window.VisualInfo.Visual, 0/*AllocNone*/); window.EventMask = EventMask.StructureNotifyMask | EventMask.SubstructureNotifyMask | EventMask.ExposureMask | - EventMask.KeyReleaseMask | EventMask.KeyPressMask | + EventMask.KeyReleaseMask | EventMask.KeyPressMask | EventMask.KeymapStateMask | EventMask.PointerMotionMask | EventMask.FocusChangeMask | EventMask.ButtonPressMask | EventMask.ButtonReleaseMask | EventMask.EnterWindowMask | EventMask.LeaveWindowMask; @@ -645,6 +648,17 @@ namespace OpenTK.Platform.X11 case XEventName.KeyPress: driver.ProcessEvent(ref e); + int status = Functions.XLookupString(ref e.KeyEvent, characters, characters.Length, null, IntPtr.Zero); + + EventHandler key_press = KeyPress; + if (key_press != null) + { + for (int i = 0; i < status; i++) + { + KPEventArgs.KeyChar = (char)characters[i]; + key_press(this, KPEventArgs); + } + } break; case XEventName.KeyRelease: @@ -689,6 +703,15 @@ namespace OpenTK.Platform.X11 if (MouseEnter != null) MouseEnter(this, EventArgs.Empty); break; + + case XEventName.MappingNotify: + // 0 == MappingModifier, 1 == MappingKeyboard + if (e.MappingEvent.request == 0 || e.MappingEvent.request == 1) + { + Debug.Print("keybard mapping refreshed"); + Functions.XRefreshKeyboardMapping(ref e.MappingEvent); + } + break; default: //Debug.WriteLine(String.Format("{0} event was not handled", e.type));