Prechádzať zdrojové kódy

Merge pull request #2 from AvaloniaUI/features/keyboard-input

Features/keyboard input
danwalmsley 7 rokov pred
rodič
commit
83d3e695a3

+ 6 - 0
src/Avalonia.Native.OSX/Avalonia.Native.OSX.xcodeproj/project.pbxproj

@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
 		37A517B32159597E00FBA241 /* Screens.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37A517B22159597E00FBA241 /* Screens.mm */; };
 		37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C09D8721580FE4006A6758 /* SystemDialogs.mm */; };
+		37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37E2330E21583241000CB7E2 /* KeyTransform.mm */; };
 		5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */; };
 		AB00E4F72147CA920032A60A /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB00E4F62147CA920032A60A /* main.mm */; };
 		AB661C1E2148230F00291242 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB661C1D2148230F00291242 /* AppKit.framework */; };
@@ -17,10 +18,12 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		379860FE214DA0C000CD0246 /* KeyTransform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyTransform.h; sourceTree = "<group>"; };
 		379A4506214D0F6500CC143D /* headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = headers; path = ../headers; sourceTree = "<group>"; };
 		37A517B22159597E00FBA241 /* Screens.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Screens.mm; sourceTree = "<group>"; };
 		37C09D8721580FE4006A6758 /* SystemDialogs.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SystemDialogs.mm; sourceTree = "<group>"; };
 		37C09D8A21581EF2006A6758 /* window.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = window.h; sourceTree = "<group>"; };
+		37E2330E21583241000CB7E2 /* KeyTransform.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyTransform.mm; sourceTree = "<group>"; };
 		5B8BD94E215BFEA6005ED2A7 /* clipboard.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard.mm; sourceTree = "<group>"; };
 		AB00E4F62147CA920032A60A /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
 		AB661C1D2148230F00291242 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
@@ -57,6 +60,8 @@
 				379A4506214D0F6500CC143D /* headers */,
 				AB8F7D6A21482D7F0057DBA5 /* platformthreading.mm */,
 				AB661C212148288600291242 /* common.h */,
+				379860FE214DA0C000CD0246 /* KeyTransform.h */,
+				37E2330E21583241000CB7E2 /* KeyTransform.mm */,
 				AB661C1F2148286E00291242 /* window.mm */,
 				37C09D8A21581EF2006A6758 /* window.h */,
 				AB00E4F62147CA920032A60A /* main.mm */,
@@ -144,6 +149,7 @@
 			files = (
 				5B8BD94F215BFEA6005ED2A7 /* clipboard.mm in Sources */,
 				AB8F7D6B21482D7F0057DBA5 /* platformthreading.mm in Sources */,
+				37E2330F21583241000CB7E2 /* KeyTransform.mm in Sources */,
 				37A517B32159597E00FBA241 /* Screens.mm in Sources */,
 				AB00E4F72147CA920032A60A /* main.mm in Sources */,
 				37C09D8821580FE4006A6758 /* SystemDialogs.mm in Sources */,

+ 9 - 0
src/Avalonia.Native.OSX/KeyTransform.h

@@ -0,0 +1,9 @@
+#ifndef keytransform_h
+#define keytransform_h
+#include "common.h"
+#include "key.h"
+#include <map>
+
+extern std::map<int, AvnKey> s_KeyMap;
+
+#endif

+ 238 - 0
src/Avalonia.Native.OSX/KeyTransform.mm

@@ -0,0 +1,238 @@
+#include "KeyTransform.h"
+
+const int kVK_ANSI_A = 0x00;
+const int kVK_ANSI_S = 0x01;
+const int kVK_ANSI_D = 0x02;
+const int kVK_ANSI_F = 0x03;
+const int kVK_ANSI_H = 0x04;
+const int kVK_ANSI_G = 0x05;
+const int kVK_ANSI_Z = 0x06;
+const int kVK_ANSI_X = 0x07;
+const int kVK_ANSI_C = 0x08;
+const int kVK_ANSI_V = 0x09;
+const int kVK_ANSI_B = 0x0B;
+const int kVK_ANSI_Q = 0x0C;
+const int kVK_ANSI_W = 0x0D;
+const int kVK_ANSI_E = 0x0E;
+const int kVK_ANSI_R = 0x0F;
+const int kVK_ANSI_Y = 0x10;
+const int kVK_ANSI_T = 0x11;
+const int kVK_ANSI_1 = 0x12;
+const int kVK_ANSI_2 = 0x13;
+const int kVK_ANSI_3 = 0x14;
+const int kVK_ANSI_4 = 0x15;
+const int kVK_ANSI_6 = 0x16;
+const int kVK_ANSI_5 = 0x17;
+const int kVK_ANSI_Equal = 0x18;
+const int kVK_ANSI_9 = 0x19;
+const int kVK_ANSI_7 = 0x1A;
+const int kVK_ANSI_Minus = 0x1B;
+const int kVK_ANSI_8 = 0x1C;
+const int kVK_ANSI_0 = 0x1D;
+const int kVK_ANSI_RightBracket = 0x1E;
+const int kVK_ANSI_O = 0x1F;
+const int kVK_ANSI_U = 0x20;
+const int kVK_ANSI_LeftBracket = 0x21;
+const int kVK_ANSI_I = 0x22;
+const int kVK_ANSI_P = 0x23;
+const int kVK_ANSI_L = 0x25;
+const int kVK_ANSI_J = 0x26;
+const int kVK_ANSI_Quote = 0x27;
+const int kVK_ANSI_K = 0x28;
+const int kVK_ANSI_Semicolon = 0x29;
+const int kVK_ANSI_Backslash = 0x2A;
+const int kVK_ANSI_Comma = 0x2B;
+const int kVK_ANSI_Slash = 0x2C;
+const int kVK_ANSI_N = 0x2D;
+const int kVK_ANSI_M = 0x2E;
+const int kVK_ANSI_Period = 0x2F;
+const int kVK_ANSI_Grave = 0x32;
+const int kVK_ANSI_KeypadDecimal = 0x41;
+const int kVK_ANSI_KeypadMultiply = 0x43;
+const int kVK_ANSI_KeypadPlus = 0x45;
+const int kVK_ANSI_KeypadClear = 0x47;
+const int kVK_ANSI_KeypadDivide = 0x4B;
+const int kVK_ANSI_KeypadEnter = 0x4C;
+const int kVK_ANSI_KeypadMinus = 0x4E;
+const int kVK_ANSI_KeypadEquals = 0x51;
+const int kVK_ANSI_Keypad0 = 0x52;
+const int kVK_ANSI_Keypad1 = 0x53;
+const int kVK_ANSI_Keypad2 = 0x54;
+const int kVK_ANSI_Keypad3 = 0x55;
+const int kVK_ANSI_Keypad4 = 0x56;
+const int kVK_ANSI_Keypad5 = 0x57;
+const int kVK_ANSI_Keypad6 = 0x58;
+const int kVK_ANSI_Keypad7 = 0x59;
+const int kVK_ANSI_Keypad8 = 0x5B;
+const int kVK_ANSI_Keypad9 = 0x5C;
+const int kVK_Return = 0x24;
+const int kVK_Tab = 0x30;
+const int kVK_Space = 0x31;
+const int kVK_Delete = 0x33;
+const int kVK_Escape = 0x35;
+const int kVK_Command = 0x37;
+const int kVK_Shift = 0x38;
+const int kVK_CapsLock = 0x39;
+const int kVK_Option = 0x3A;
+const int kVK_Control = 0x3B;
+const int kVK_RightCommand = 0x36;
+const int kVK_RightShift = 0x3C;
+const int kVK_RightOption = 0x3D;
+const int kVK_RightControl = 0x3E;
+const int kVK_Function = 0x3F;
+const int kVK_F17 = 0x40;
+const int kVK_VolumeUp = 0x48;
+const int kVK_VolumeDown = 0x49;
+const int kVK_Mute = 0x4A;
+const int kVK_F18 = 0x4F;
+const int kVK_F19 = 0x50;
+const int kVK_F20 = 0x5A;
+const int kVK_F5 = 0x60;
+const int kVK_F6 = 0x61;
+const int kVK_F7 = 0x62;
+const int kVK_F3 = 0x63;
+const int kVK_F8 = 0x64;
+const int kVK_F9 = 0x65;
+const int kVK_F11 = 0x67;
+const int kVK_F13 = 0x69;
+const int kVK_F16 = 0x6A;
+const int kVK_F14 = 0x6B;
+const int kVK_F10 = 0x6D;
+const int kVK_F12 = 0x6F;
+const int kVK_F15 = 0x71;
+const int kVK_Help = 0x72;
+const int kVK_Home = 0x73;
+const int kVK_PageUp = 0x74;
+const int kVK_ForwardDelete = 0x75;
+const int kVK_F4 = 0x76;
+const int kVK_End = 0x77;
+const int kVK_F2 = 0x78;
+const int kVK_PageDown = 0x79;
+const int kVK_F1 = 0x7A;
+const int kVK_LeftArrow = 0x7B;
+const int kVK_RightArrow = 0x7C;
+const int kVK_DownArrow = 0x7D;
+const int kVK_UpArrow = 0x7E;
+const int kVK_ISO_Section = 0x0A;
+const int kVK_JIS_Yen = 0x5D;
+const int kVK_JIS_Underscore = 0x5E;
+const int kVK_JIS_KeypadComma = 0x5F;
+const int kVK_JIS_Eisu = 0x66;
+const int kVK_JIS_Kana = 0x68;
+
+ std::map<int, AvnKey> s_KeyMap =
+ {
+    {0, A},
+    {1, S},
+    {kVK_ANSI_D, D},
+    {kVK_ANSI_F, F},
+    {kVK_ANSI_H, H},
+    {kVK_ANSI_G, G},
+    {kVK_ANSI_Z, Z},
+    {kVK_ANSI_X, X},
+    {kVK_ANSI_C, C},
+    {kVK_ANSI_V, V},
+    {kVK_ANSI_B, B},
+    {kVK_ANSI_Q, Q},
+    {kVK_ANSI_W, W},
+    {kVK_ANSI_E, E},
+    {kVK_ANSI_R, R},
+    {kVK_ANSI_Y, Y},
+    {kVK_ANSI_T, T},
+    {kVK_ANSI_1, D1},
+    {kVK_ANSI_2, D2},
+    {kVK_ANSI_3, D3},
+    {kVK_ANSI_4, D4},
+    {kVK_ANSI_6, D6},
+    {kVK_ANSI_5, D5},
+    //{kVK_ANSI_Equal, ?},
+    {kVK_ANSI_9, D9},
+    {kVK_ANSI_7, D7},
+    {kVK_ANSI_Minus, OemMinus},
+    {kVK_ANSI_8, D8},
+    {kVK_ANSI_0, D0},
+    {kVK_ANSI_RightBracket, OemCloseBrackets},
+    {kVK_ANSI_O, O},
+    {kVK_ANSI_U, U},
+    {kVK_ANSI_LeftBracket, OemOpenBrackets},
+    {kVK_ANSI_I, I},
+    {kVK_ANSI_P, P},
+    {kVK_ANSI_L, L},
+    {kVK_ANSI_J, J},
+    {kVK_ANSI_Quote, OemQuotes},
+    {kVK_ANSI_K, AvnKeyK},
+    {kVK_ANSI_Semicolon, OemSemicolon},
+    {kVK_ANSI_Backslash, OemBackslash},
+    {kVK_ANSI_Comma, OemComma},
+    //{kVK_ANSI_Slash, ?},
+    {kVK_ANSI_N, N},
+    {kVK_ANSI_M, M},
+    {kVK_ANSI_Period, OemPeriod},
+    //{kVK_ANSI_Grave, ?},
+    {kVK_ANSI_KeypadDecimal, Decimal},
+    {kVK_ANSI_KeypadMultiply, Multiply},
+    {kVK_ANSI_KeypadPlus, OemPlus},
+    {kVK_ANSI_KeypadClear, AvnKeyClear},
+    {kVK_ANSI_KeypadDivide, Divide},
+    {kVK_ANSI_KeypadEnter, AvnKeyEnter},
+    {kVK_ANSI_KeypadMinus, OemMinus},
+    //{kVK_ANSI_KeypadEquals, ?},
+    {kVK_ANSI_Keypad0, NumPad0},
+    {kVK_ANSI_Keypad1, NumPad1},
+    {kVK_ANSI_Keypad2, NumPad2},
+    {kVK_ANSI_Keypad3, NumPad3},
+    {kVK_ANSI_Keypad4, NumPad4},
+    {kVK_ANSI_Keypad5, NumPad5},
+    {kVK_ANSI_Keypad6, NumPad6},
+    {kVK_ANSI_Keypad7, NumPad7},
+    {kVK_ANSI_Keypad8, NumPad8},
+    {kVK_ANSI_Keypad9, NumPad9},
+    {kVK_Return, AvnKeyReturn},
+    {kVK_Tab, AvnKeyTab},
+    {kVK_Space, Space},
+    {kVK_Delete, AvnKeyBack},
+    {kVK_Escape, Escape},
+    {kVK_Command, LWin},
+    {kVK_Shift, LeftShift},
+    {kVK_CapsLock, AvnKeyCapsLock},
+    {kVK_Option, LeftAlt},
+    {kVK_Control, LeftCtrl},
+    {kVK_RightCommand, RWin},
+    {kVK_RightShift, RightShift},
+    {kVK_RightOption, RightAlt},
+    {kVK_RightControl, RightCtrl},
+    //{kVK_Function, ?},
+    {kVK_F17, F17},
+    {kVK_VolumeUp, VolumeUp},
+    {kVK_VolumeDown, VolumeDown},
+    {kVK_Mute, VolumeMute},
+    {kVK_F18, F18},
+    {kVK_F19, F19},
+    {kVK_F20, F20},
+    {kVK_F5, F5},
+    {kVK_F6, F6},
+    {kVK_F7, F7},
+    {kVK_F3, F3},
+    {kVK_F8, F8},
+    {kVK_F9, F9},
+    {kVK_F11, F11},
+    {kVK_F13, F13},
+    {kVK_F16, F16},
+    {kVK_F14, F14},
+    {kVK_F10, F10},
+    {kVK_F12, F12},
+    {kVK_F15, F15},
+    {kVK_Help, Help},
+    {kVK_Home, Home},
+    {kVK_PageUp, PageUp},
+    {kVK_ForwardDelete, Delete},
+    {kVK_F4, F4},
+    {kVK_End, End},
+    {kVK_F2, F2},
+    {kVK_PageDown, PageDown},
+    {kVK_F1, F1},
+    {kVK_LeftArrow, Left},
+    {kVK_RightArrow, Right},
+    {kVK_DownArrow, Down},
+    {kVK_UpArrow, Up}
+};

+ 1 - 1
src/Avalonia.Native.OSX/window.h

@@ -11,7 +11,7 @@
 
 class WindowBaseImpl;
 
-@interface AvnView : NSView
+@interface AvnView : NSView<NSTextInputClient>
 -(AvnView*) initWithParent: (WindowBaseImpl*) parent;
 -(NSEvent*) lastMouseDownEvent;
 -(AvnPoint) translateLocalPoint:(AvnPoint)pt;

+ 102 - 1
src/Avalonia.Native.OSX/window.mm

@@ -1,5 +1,6 @@
 #include "common.h"
 #include "window.h"
+#include "KeyTransform.h"
 
 class WindowBaseImpl : public ComSingleObject<IAvnWindowBase, &IID_IAvnWindowBase>, public INSWindowHolder
 {
@@ -215,6 +216,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
     NSTrackingArea* _area;
     bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isMouseOver;
     NSEvent* _lastMouseDownEvent;
+    bool _lastKeyHandled;
 }
 
 - (NSEvent*) lastMouseDownEvent
@@ -231,6 +233,16 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
 }
 
 - (BOOL)isOpaque
+{
+    return false;
+}
+
+- (BOOL)acceptsFirstResponder
+{
+    return true;
+}
+
+- (BOOL)canBecomeKeyView
 {
     return true;
 }
@@ -363,6 +375,7 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
 
 - (void)mouseEvent:(NSEvent *)event withType:(AvnRawMouseEventType) type
 {
+    [self becomeFirstResponder];
     auto localPoint = [self convertPoint:[event locationInWindow] toView:self];
     auto avnPoint = [self toAvnPoint:localPoint];
     auto point = [self translateLocalPoint:avnPoint];
@@ -481,6 +494,34 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
     _isMouseOver = false;
     [self mouseEvent:event withType:LeaveWindow];
     [super mouseExited:event];
+} 
+
+- (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type
+{ 
+    auto key = s_KeyMap[[event keyCode]];
+    
+    auto timestamp = [event timestamp] * 1000;
+    auto modifiers = [self getModifiers:[event modifierFlags]];
+     
+    _lastKeyHandled = _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key);
+}
+
+- (BOOL)performKeyEquivalent:(NSEvent *)event
+{
+    return _lastKeyHandled;
+}
+
+- (void)keyDown:(NSEvent *)event
+{
+    [self keyboardEvent:event withType:KeyDown];
+    [[self inputContext] handleEvent:event];
+    [super keyDown:event];
+}
+
+- (void)keyUp:(NSEvent *)event
+{
+    [self keyboardEvent:event withType:KeyUp];
+    [super keyUp:event];
 }
 
 - (AvnInputModifiers)getModifiers:(NSEventModifierFlags)mod
@@ -505,6 +546,61 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
     
     return (AvnInputModifiers)rv;
 }
+
+- (BOOL)hasMarkedText
+{
+    return _lastKeyHandled;
+}
+
+- (NSRange)markedRange
+{
+    return NSMakeRange(NSNotFound, 0);
+}
+
+- (NSRange)selectedRange
+{
+    return NSMakeRange(NSNotFound, 0);
+}
+
+- (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
+{
+    
+}
+
+- (void)unmarkText
+{
+    
+}
+
+- (NSArray<NSAttributedStringKey> *)validAttributesForMarkedText
+{
+    return [NSArray new];
+}
+
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange
+{
+    return [NSAttributedString new];
+}
+
+- (void)insertText:(id)string replacementRange:(NSRange)replacementRange
+{
+    if(!_lastKeyHandled)
+    {
+        _lastKeyHandled = _parent->BaseEvents->RawTextInputEvent(0, [string UTF8String]);
+    }
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)point
+{
+    return 0;
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange
+{
+    CGRect result;
+    
+    return result;
+}
 @end
 
 
@@ -539,8 +635,13 @@ NSArray* AllLoopModes = [NSArray arrayWithObjects: NSDefaultRunLoopMode, NSEvent
 
 -(void)becomeKeyWindow
 {
-    [super becomeKeyWindow];
     _parent->BaseEvents->Activated();
+    [super becomeKeyWindow];
+}
+
+- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
+{
+    return true;
 }
 
 -(void)resignKeyWindow

+ 31 - 1
src/Avalonia.Native/WindowImplBase.cs

@@ -18,12 +18,14 @@ namespace Avalonia.Native
         private object _syncRoot = new object();
         private bool _deferredRendering = true;
         private readonly IMouseDevice _mouse;
+        private readonly IKeyboardDevice _keyboard;
         private Size _savedLogicalSize;
         private Size _lastRenderedLogicalSize;
         private double _savedScaling;
 
         public WindowBaseImpl()
         {
+            _keyboard = AvaloniaLocator.Current.GetService<IKeyboardDevice>();
             _mouse = AvaloniaLocator.Current.GetService<IMouseDevice>();
         }
 
@@ -143,6 +145,17 @@ namespace Avalonia.Native
                 _parent.RawMouseEvent(type, timeStamp, modifiers, point, delta);
             }
 
+            bool IAvnWindowBaseEvents.RawKeyEvent(AvnRawKeyEventType type, uint timeStamp, AvnInputModifiers modifiers, uint key)
+            {
+                return _parent.RawKeyEvent(type, timeStamp, modifiers, key);
+            }
+
+            bool IAvnWindowBaseEvents.RawTextInputEvent(uint timeStamp, string text)
+            {
+                return _parent.RawTextInputEvent(timeStamp, text);
+            }
+
+
             void IAvnWindowBaseEvents.ScalingChanged(double scaling)
             {
                 _parent._savedScaling = scaling;
@@ -159,12 +172,29 @@ namespace Avalonia.Native
             }
         }
 
-
         public void Activate()
         {
             _native.Activate();
         }
 
+        public bool RawTextInputEvent(uint timeStamp, string text)
+        {
+            var args = new RawTextInputEventArgs(_keyboard, timeStamp, text);
+
+            Input?.Invoke(args);
+
+            return args.Handled;
+        }
+
+        public bool RawKeyEvent(AvnRawKeyEventType type, uint timeStamp, AvnInputModifiers modifiers, uint key)
+        {
+            var args = new RawKeyEventArgs(_keyboard, timeStamp, (RawKeyEventType)type, (Key)key, (InputModifiers)modifiers);
+
+            Input?.Invoke(args);
+
+            return args.Handled;
+        }
+
         public void RawMouseEvent(AvnRawMouseEventType type, uint timeStamp, AvnInputModifiers modifiers, AvnPoint point, AvnVector delta)
         {
             Dispatcher.UIThread.RunJobs(DispatcherPriority.Input + 1);

+ 10 - 1
src/headers/avalonia-native.h

@@ -1,4 +1,5 @@
 #include "com.h"
+#include "key.h"
 
 #define AVNCOM(name, id) COMINTERFACE(name, 2e2cda0a, 9ae5, 4f1b, 8e, 20, 08, 1a, 04, 27, 9f, id)
 
@@ -70,9 +71,15 @@ enum AvnRawMouseEventType
     NonClientLeftButtonDown
 };
 
+enum AvnRawKeyEventType
+{
+    KeyDown,
+    KeyUp
+};
+
 enum AvnInputModifiers
 {
-    None = 0,
+    AvnInputModifiersNone = 0,
     Alt = 1,
     Control = 2,
     Shift = 4,
@@ -148,6 +155,8 @@ AVNCOM(IAvnWindowBaseEvents, 05) : IUnknown
                                 AvnInputModifiers modifiers,
                                 AvnPoint point,
                                 AvnVector delta) = 0;
+    virtual bool RawKeyEvent (AvnRawKeyEventType type, unsigned int timeStamp, AvnInputModifiers modifiers, unsigned int key) = 0;
+    virtual bool RawTextInputEvent (unsigned int timeStamp, const char* text) = 0;
     virtual void ScalingChanged(double scaling) = 0;
     virtual void RunRenderPriorityJobs() = 0;
 };

+ 1020 - 0
src/headers/key.h

@@ -0,0 +1,1020 @@
+#ifndef _KEY_H_
+#define _KEY_H_
+
+/// <summary>
+/// Defines the keys available on a keyboard.
+/// </summary>
+enum AvnKey
+{
+    /// <summary>
+    /// No key pressed.
+    /// </summary>
+    AvnKeyNone = 0,
+    
+    /// <summary>
+    /// The Cancel key.
+    /// </summary>
+    AvnKeyCancel = 1,
+    
+    /// <summary>
+    /// The Back key.
+    /// </summary>
+    AvnKeyBack = 2,
+    
+    /// <summary>
+    /// The Tab key.
+    /// </summary>
+    AvnKeyTab = 3,
+    
+    /// <summary>
+    /// The Linefeed key.
+    /// </summary>
+    AvnKeyLineFeed = 4,
+    
+    /// <summary>
+    /// The Clear key.
+    /// </summary>
+    AvnKeyClear = 5,
+    
+    /// <summary>
+    /// The Return key.
+    /// </summary>
+    AvnKeyReturn = 6,
+    
+    /// <summary>
+    /// The Enter key.
+    /// </summary>
+    AvnKeyEnter = 6,
+    
+    /// <summary>
+    /// The Pause key.
+    /// </summary>
+    AvnKeyPause = 7,
+    
+    /// <summary>
+    /// The Caps Lock key.
+    /// </summary>
+    AvnKeyCapsLock = 8,
+    
+    /// <summary>
+    /// The Caps Lock key.
+    /// </summary>
+    AvnKeyCapital = 8,
+    
+    /// <summary>
+    /// The IME Hangul mode key.
+    /// </summary>
+    AvnKeyHangulMode = 9,
+    
+    /// <summary>
+    /// The IME Kana mode key.
+    /// </summary>
+    AvnKeyKanaMode = 9,
+    
+    /// <summary>
+    /// The IME Junja mode key.
+    /// </summary>
+    AvnKeyJunjaMode = 10,
+    
+    /// <summary>
+    /// The IME Final mode key.
+    /// </summary>
+    AvnKeyFinalMode = 11,
+    
+    /// <summary>
+    /// The IME Kanji mode key.
+    /// </summary>
+    AvnKeyKanjiMode = 12,
+    
+    /// <summary>
+    /// The IME Hanja mode key.
+    /// </summary>
+    HanjaMode = 12,
+    
+    /// <summary>
+    /// The Escape key.
+    /// </summary>
+    Escape = 13,
+    
+    /// <summary>
+    /// The IME Convert key.
+    /// </summary>
+    ImeConvert = 14,
+    
+    /// <summary>
+    /// The IME NonConvert key.
+    /// </summary>
+    ImeNonConvert = 15,
+    
+    /// <summary>
+    /// The IME Accept key.
+    /// </summary>
+    ImeAccept = 16,
+    
+    /// <summary>
+    /// The IME Mode change key.
+    /// </summary>
+    ImeModeChange = 17,
+    
+    /// <summary>
+    /// The space bar.
+    /// </summary>
+    Space = 18,
+    
+    /// <summary>
+    /// The Page Up key.
+    /// </summary>
+    PageUp = 19,
+    
+    /// <summary>
+    /// The Page Up key.
+    /// </summary>
+    Prior = 19,
+    
+    /// <summary>
+    /// The Page Down key.
+    /// </summary>
+    PageDown = 20,
+    
+    /// <summary>
+    /// The Page Down key.
+    /// </summary>
+    Next = 20,
+    
+    /// <summary>
+    /// The End key.
+    /// </summary>
+    End = 21,
+    
+    /// <summary>
+    /// The Home key.
+    /// </summary>
+    Home = 22,
+    
+    /// <summary>
+    /// The Left arrow key.
+    /// </summary>
+    Left = 23,
+    
+    /// <summary>
+    /// The Up arrow key.
+    /// </summary>
+    Up = 24,
+    
+    /// <summary>
+    /// The Right arrow key.
+    /// </summary>
+    Right = 25,
+    
+    /// <summary>
+    /// The Down arrow key.
+    /// </summary>
+    Down = 26,
+    
+    /// <summary>
+    /// The Select key.
+    /// </summary>
+    Select = 27,
+    
+    /// <summary>
+    /// The Print key.
+    /// </summary>
+    Print = 28,
+    
+    /// <summary>
+    /// The Execute key.
+    /// </summary>
+    Execute = 29,
+    
+    /// <summary>
+    /// The Print Screen key.
+    /// </summary>
+    Snapshot = 30,
+    
+    /// <summary>
+    /// The Print Screen key.
+    /// </summary>
+    PrintScreen = 30,
+    
+    /// <summary>
+    /// The Insert key.
+    /// </summary>
+    Insert = 31,
+    
+    /// <summary>
+    /// The Delete key.
+    /// </summary>
+    Delete = 32,
+    
+    /// <summary>
+    /// The Help key.
+    /// </summary>
+    Help = 33,
+    
+    /// <summary>
+    /// The 0 key.
+    /// </summary>
+    D0 = 34,
+    
+    /// <summary>
+    /// The 1 key.
+    /// </summary>
+    D1 = 35,
+    
+    /// <summary>
+    /// The 2 key.
+    /// </summary>
+    D2 = 36,
+    
+    /// <summary>
+    /// The 3 key.
+    /// </summary>
+    D3 = 37,
+    
+    /// <summary>
+    /// The 4 key.
+    /// </summary>
+    D4 = 38,
+    
+    /// <summary>
+    /// The 5 key.
+    /// </summary>
+    D5 = 39,
+    
+    /// <summary>
+    /// The 6 key.
+    /// </summary>
+    D6 = 40,
+    
+    /// <summary>
+    /// The 7 key.
+    /// </summary>
+    D7 = 41,
+    
+    /// <summary>
+    /// The 8 key.
+    /// </summary>
+    D8 = 42,
+    
+    /// <summary>
+    /// The 9 key.
+    /// </summary>
+    D9 = 43,
+    
+    /// <summary>
+    /// The A key.
+    /// </summary>
+    A = 44,
+    
+    /// <summary>
+    /// The B key.
+    /// </summary>
+    B = 45,
+    
+    /// <summary>
+    /// The C key.
+    /// </summary>
+    C = 46,
+    
+    /// <summary>
+    /// The D key.
+    /// </summary>
+    D = 47,
+    
+    /// <summary>
+    /// The E key.
+    /// </summary>
+    E = 48,
+    
+    /// <summary>
+    /// The F key.
+    /// </summary>
+    F = 49,
+    
+    /// <summary>
+    /// The G key.
+    /// </summary>
+    G = 50,
+    
+    /// <summary>
+    /// The H key.
+    /// </summary>
+    H = 51,
+    
+    /// <summary>
+    /// The I key.
+    /// </summary>
+    I = 52,
+    
+    /// <summary>
+    /// The J key.
+    /// </summary>
+    J = 53,
+    
+    /// <summary>
+    /// The K key.
+    /// </summary>
+    AvnKeyK = 54,
+    
+    /// <summary>
+    /// The L key.
+    /// </summary>
+    L = 55,
+    
+    /// <summary>
+    /// The M key.
+    /// </summary>
+    M = 56,
+    
+    /// <summary>
+    /// The N key.
+    /// </summary>
+    N = 57,
+    
+    /// <summary>
+    /// The O key.
+    /// </summary>
+    O = 58,
+    
+    /// <summary>
+    /// The P key.
+    /// </summary>
+    P = 59,
+    
+    /// <summary>
+    /// The Q key.
+    /// </summary>
+    Q = 60,
+    
+    /// <summary>
+    /// The R key.
+    /// </summary>
+    R = 61,
+    
+    /// <summary>
+    /// The S key.
+    /// </summary>
+    S = 62,
+    
+    /// <summary>
+    /// The T key.
+    /// </summary>
+    T = 63,
+    
+    /// <summary>
+    /// The U key.
+    /// </summary>
+    U = 64,
+    
+    /// <summary>
+    /// The V key.
+    /// </summary>
+    V = 65,
+    
+    /// <summary>
+    /// The W key.
+    /// </summary>
+    W = 66,
+    
+    /// <summary>
+    /// The X key.
+    /// </summary>
+    X = 67,
+    
+    /// <summary>
+    /// The Y key.
+    /// </summary>
+    Y = 68,
+    
+    /// <summary>
+    /// The Z key.
+    /// </summary>
+    Z = 69,
+    
+    /// <summary>
+    /// The left Windows key.
+    /// </summary>
+    LWin = 70,
+    
+    /// <summary>
+    /// The right Windows key.
+    /// </summary>
+    RWin = 71,
+    
+    /// <summary>
+    /// The Application key.
+    /// </summary>
+    Apps = 72,
+    
+    /// <summary>
+    /// The Sleep key.
+    /// </summary>
+    Sleep = 73,
+    
+    /// <summary>
+    /// The 0 key on the numeric keypad.
+    /// </summary>
+    NumPad0 = 74,
+    
+    /// <summary>
+    /// The 1 key on the numeric keypad.
+    /// </summary>
+    NumPad1 = 75,
+    
+    /// <summary>
+    /// The 2 key on the numeric keypad.
+    /// </summary>
+    NumPad2 = 76,
+    
+    /// <summary>
+    /// The 3 key on the numeric keypad.
+    /// </summary>
+    NumPad3 = 77,
+    
+    /// <summary>
+    /// The 4 key on the numeric keypad.
+    /// </summary>
+    NumPad4 = 78,
+    
+    /// <summary>
+    /// The 5 key on the numeric keypad.
+    /// </summary>
+    NumPad5 = 79,
+    
+    /// <summary>
+    /// The 6 key on the numeric keypad.
+    /// </summary>
+    NumPad6 = 80,
+    
+    /// <summary>
+    /// The 7 key on the numeric keypad.
+    /// </summary>
+    NumPad7 = 81,
+    
+    /// <summary>
+    /// The 8 key on the numeric keypad.
+    /// </summary>
+    NumPad8 = 82,
+    
+    /// <summary>
+    /// The 9 key on the numeric keypad.
+    /// </summary>
+    NumPad9 = 83,
+    
+    /// <summary>
+    /// The Multiply key.
+    /// </summary>
+    Multiply = 84,
+    
+    /// <summary>
+    /// The Add key.
+    /// </summary>
+    Add = 85,
+    
+    /// <summary>
+    /// The Separator key.
+    /// </summary>
+    Separator = 86,
+    
+    /// <summary>
+    /// The Subtract key.
+    /// </summary>
+    Subtract = 87,
+    
+    /// <summary>
+    /// The Decimal key.
+    /// </summary>
+    Decimal = 88,
+    
+    /// <summary>
+    /// The Divide key.
+    /// </summary>
+    Divide = 89,
+    
+    /// <summary>
+    /// The F1 key.
+    /// </summary>
+    F1 = 90,
+    
+    /// <summary>
+    /// The F2 key.
+    /// </summary>
+    F2 = 91,
+    
+    /// <summary>
+    /// The F3 key.
+    /// </summary>
+    F3 = 92,
+    
+    /// <summary>
+    /// The F4 key.
+    /// </summary>
+    F4 = 93,
+    
+    /// <summary>
+    /// The F5 key.
+    /// </summary>
+    F5 = 94,
+    
+    /// <summary>
+    /// The F6 key.
+    /// </summary>
+    F6 = 95,
+    
+    /// <summary>
+    /// The F7 key.
+    /// </summary>
+    F7 = 96,
+    
+    /// <summary>
+    /// The F8 key.
+    /// </summary>
+    F8 = 97,
+    
+    /// <summary>
+    /// The F9 key.
+    /// </summary>
+    F9 = 98,
+    
+    /// <summary>
+    /// The F10 key.
+    /// </summary>
+    F10 = 99,
+    
+    /// <summary>
+    /// The F11 key.
+    /// </summary>
+    F11 = 100,
+    
+    /// <summary>
+    /// The F12 key.
+    /// </summary>
+    F12 = 101,
+    
+    /// <summary>
+    /// The F13 key.
+    /// </summary>
+    F13 = 102,
+    
+    /// <summary>
+    /// The F14 key.
+    /// </summary>
+    F14 = 103,
+    
+    /// <summary>
+    /// The F15 key.
+    /// </summary>
+    F15 = 104,
+    
+    /// <summary>
+    /// The F16 key.
+    /// </summary>
+    F16 = 105,
+    
+    /// <summary>
+    /// The F17 key.
+    /// </summary>
+    F17 = 106,
+    
+    /// <summary>
+    /// The F18 key.
+    /// </summary>
+    F18 = 107,
+    
+    /// <summary>
+    /// The F19 key.
+    /// </summary>
+    F19 = 108,
+    
+    /// <summary>
+    /// The F20 key.
+    /// </summary>
+    F20 = 109,
+    
+    /// <summary>
+    /// The F21 key.
+    /// </summary>
+    F21 = 110,
+    
+    /// <summary>
+    /// The F22 key.
+    /// </summary>
+    F22 = 111,
+    
+    /// <summary>
+    /// The F23 key.
+    /// </summary>
+    F23 = 112,
+    
+    /// <summary>
+    /// The F24 key.
+    /// </summary>
+    F24 = 113,
+    
+    /// <summary>
+    /// The Numlock key.
+    /// </summary>
+    NumLock = 114,
+    
+    /// <summary>
+    /// The Scroll key.
+    /// </summary>
+    Scroll = 115,
+    
+    /// <summary>
+    /// The left Shift key.
+    /// </summary>
+    LeftShift = 116,
+    
+    /// <summary>
+    /// The right Shift key.
+    /// </summary>
+    RightShift = 117,
+    
+    /// <summary>
+    /// The left Ctrl key.
+    /// </summary>
+    LeftCtrl = 118,
+    
+    /// <summary>
+    /// The right Ctrl key.
+    /// </summary>
+    RightCtrl = 119,
+    
+    /// <summary>
+    /// The left Alt key.
+    /// </summary>
+    LeftAlt = 120,
+    
+    /// <summary>
+    /// The right Alt key.
+    /// </summary>
+    RightAlt = 121,
+    
+    /// <summary>
+    /// The browser Back key.
+    /// </summary>
+    BrowserBack = 122,
+    
+    /// <summary>
+    /// The browser Forward key.
+    /// </summary>
+    BrowserForward = 123,
+    
+    /// <summary>
+    /// The browser Refresh key.
+    /// </summary>
+    BrowserRefresh = 124,
+    
+    /// <summary>
+    /// The browser Stop key.
+    /// </summary>
+    BrowserStop = 125,
+    
+    /// <summary>
+    /// The browser Search key.
+    /// </summary>
+    BrowserSearch = 126,
+    
+    /// <summary>
+    /// The browser Favorites key.
+    /// </summary>
+    BrowserFavorites = 127,
+    
+    /// <summary>
+    /// The browser Home key.
+    /// </summary>
+    BrowserHome = 128,
+    
+    /// <summary>
+    /// The Volume Mute key.
+    /// </summary>
+    VolumeMute = 129,
+    
+    /// <summary>
+    /// The Volume Down key.
+    /// </summary>
+    VolumeDown = 130,
+    
+    /// <summary>
+    /// The Volume Up key.
+    /// </summary>
+    VolumeUp = 131,
+    
+    /// <summary>
+    /// The media Next Track key.
+    /// </summary>
+    MediaNextTrack = 132,
+    
+    /// <summary>
+    /// The media Previous Track key.
+    /// </summary>
+    MediaPreviousTrack = 133,
+    
+    /// <summary>
+    /// The media Stop key.
+    /// </summary>
+    MediaStop = 134,
+    
+    /// <summary>
+    /// The media Play/Pause key.
+    /// </summary>
+    MediaPlayPause = 135,
+    
+    /// <summary>
+    /// The Launch Mail key.
+    /// </summary>
+    LaunchMail = 136,
+    
+    /// <summary>
+    /// The Select Media key.
+    /// </summary>
+    SelectMedia = 137,
+    
+    /// <summary>
+    /// The Launch Application 1 key.
+    /// </summary>
+    LaunchApplication1 = 138,
+    
+    /// <summary>
+    /// The Launch Application 2 key.
+    /// </summary>
+    LaunchApplication2 = 139,
+    
+    /// <summary>
+    /// The OEM Semicolon key.
+    /// </summary>
+    OemSemicolon = 140,
+    
+    /// <summary>
+    /// The OEM 1 key.
+    /// </summary>
+    Oem1 = 140,
+    
+    /// <summary>
+    /// The OEM Plus key.
+    /// </summary>
+    OemPlus = 141,
+    
+    /// <summary>
+    /// The OEM Comma key.
+    /// </summary>
+    OemComma = 142,
+    
+    /// <summary>
+    /// The OEM Minus key.
+    /// </summary>
+    OemMinus = 143,
+    
+    /// <summary>
+    /// The OEM Period key.
+    /// </summary>
+    OemPeriod = 144,
+    
+    /// <summary>
+    /// The OEM Question Mark key.
+    /// </summary>
+    OemQuestion = 145,
+    
+    /// <summary>
+    /// The OEM 2 key.
+    /// </summary>
+    Oem2 = 145,
+    
+    /// <summary>
+    /// The OEM Tilde key.
+    /// </summary>
+    OemTilde = 146,
+    
+    /// <summary>
+    /// The OEM 3 key.
+    /// </summary>
+    Oem3 = 146,
+    
+    /// <summary>
+    /// The ABNT_C1 (Brazilian) key.
+    /// </summary>
+    AbntC1 = 147,
+    
+    /// <summary>
+    /// The ABNT_C2 (Brazilian) key.
+    /// </summary>
+    AbntC2 = 148,
+    
+    /// <summary>
+    /// The OEM Open Brackets key.
+    /// </summary>
+    OemOpenBrackets = 149,
+    
+    /// <summary>
+    /// The OEM 4 key.
+    /// </summary>
+    Oem4 = 149,
+    
+    /// <summary>
+    /// The OEM Pipe key.
+    /// </summary>
+    OemPipe = 150,
+    
+    /// <summary>
+    /// The OEM 5 key.
+    /// </summary>
+    Oem5 = 150,
+    
+    /// <summary>
+    /// The OEM Close Brackets key.
+    /// </summary>
+    OemCloseBrackets = 151,
+    
+    /// <summary>
+    /// The OEM 6 key.
+    /// </summary>
+    Oem6 = 151,
+    
+    /// <summary>
+    /// The OEM Quotes key.
+    /// </summary>
+    OemQuotes = 152,
+    
+    /// <summary>
+    /// The OEM 7 key.
+    /// </summary>
+    Oem7 = 152,
+    
+    /// <summary>
+    /// The OEM 8 key.
+    /// </summary>
+    Oem8 = 153,
+    
+    /// <summary>
+    /// The OEM Backslash key.
+    /// </summary>
+    OemBackslash = 154,
+    
+    /// <summary>
+    /// The OEM 3 key.
+    /// </summary>
+    Oem102 = 154,
+    
+    /// <summary>
+    /// A special key masking the real key being processed by an IME.
+    /// </summary>
+    ImeProcessed = 155,
+    
+    /// <summary>
+    /// A special key masking the real key being processed as a system key.
+    /// </summary>
+    System = 156,
+    
+    /// <summary>
+    /// The OEM ATTN key.
+    /// </summary>
+    OemAttn = 157,
+    
+    /// <summary>
+    /// The DBE_ALPHANUMERIC key.
+    /// </summary>
+    DbeAlphanumeric = 157,
+    
+    /// <summary>
+    /// The OEM Finish key.
+    /// </summary>
+    OemFinish = 158,
+    
+    /// <summary>
+    /// The DBE_KATAKANA key.
+    /// </summary>
+    DbeKatakana = 158,
+    
+    /// <summary>
+    /// The DBE_HIRAGANA key.
+    /// </summary>
+    DbeHiragana = 159,
+    
+    /// <summary>
+    /// The OEM Copy key.
+    /// </summary>
+    OemCopy = 159,
+    
+    /// <summary>
+    /// The DBE_SBCSCHAR key.
+    /// </summary>
+    DbeSbcsChar = 160,
+    
+    /// <summary>
+    /// The OEM Auto key.
+    /// </summary>
+    OemAuto = 160,
+    
+    /// <summary>
+    /// The DBE_DBCSCHAR key.
+    /// </summary>
+    DbeDbcsChar = 161,
+    
+    /// <summary>
+    /// The OEM ENLW key.
+    /// </summary>
+    OemEnlw = 161,
+    
+    /// <summary>
+    /// The OEM BackTab key.
+    /// </summary>
+    OemBackTab = 162,
+    
+    /// <summary>
+    /// The DBE_ROMAN key.
+    /// </summary>
+    DbeRoman = 162,
+    
+    /// <summary>
+    /// The DBE_NOROMAN key.
+    /// </summary>
+    DbeNoRoman = 163,
+    
+    /// <summary>
+    /// The ATTN key.
+    /// </summary>
+    Attn = 163,
+    
+    /// <summary>
+    /// The CRSEL key.
+    /// </summary>
+    CrSel = 164,
+    
+    /// <summary>
+    /// The DBE_ENTERWORDREGISTERMODE key.
+    /// </summary>
+    DbeEnterWordRegisterMode = 164,
+    
+    /// <summary>
+    /// The EXSEL key.
+    /// </summary>
+    ExSel = 165,
+    
+    /// <summary>
+    /// The DBE_ENTERIMECONFIGMODE key.
+    /// </summary>
+    DbeEnterImeConfigureMode = 165,
+    
+    /// <summary>
+    /// The ERASE EOF Key.
+    /// </summary>
+    EraseEof = 166,
+    
+    /// <summary>
+    /// The DBE_FLUSHSTRING key.
+    /// </summary>
+    DbeFlushString = 166,
+    
+    /// <summary>
+    /// The Play key.
+    /// </summary>
+    Play = 167,
+    
+    /// <summary>
+    /// The DBE_CODEINPUT key.
+    /// </summary>
+    DbeCodeInput = 167,
+    
+    /// <summary>
+    /// The DBE_NOCODEINPUT key.
+    /// </summary>
+    DbeNoCodeInput = 168,
+    
+    /// <summary>
+    /// The Zoom key.
+    /// </summary>
+    Zoom = 168,
+    
+    /// <summary>
+    /// Reserved for future use.
+    /// </summary>
+    NoName = 169,
+    
+    /// <summary>
+    /// The DBE_DETERMINESTRING key.
+    /// </summary>
+    DbeDetermineString = 169,
+    
+    /// <summary>
+    /// The DBE_ENTERDLGCONVERSIONMODE key.
+    /// </summary>
+    DbeEnterDialogConversionMode = 170,
+    
+    /// <summary>
+    /// The PA1 key.
+    /// </summary>
+    Pa1 = 170,
+    
+    /// <summary>
+    /// The OEM Clear key.
+    /// </summary>
+    OemClear = 171,
+    
+    /// <summary>
+    /// The key is used with another key to create a single combined character.
+    /// </summary>
+    DeadCharProcessed = 172,
+};
+
+#endif