[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 2/4] xenvkbd: Move input reports to Ring.c



From: Owen Smith <owen.smith@xxxxxxxxxx>

Has the benefit of not requiring another suspend callback or debug
callback

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xenvkbd/hid.c  | 406 ++++++++---------------------------------------------
 src/xenvkbd/hid.h  |  24 +---
 src/xenvkbd/pdo.h  |  35 -----
 src/xenvkbd/ring.c | 271 +++++++++++++++++++++++++++++++++--
 src/xenvkbd/ring.h |  14 ++
 5 files changed, 337 insertions(+), 413 deletions(-)

diff --git a/src/xenvkbd/hid.c b/src/xenvkbd/hid.c
index 6db6613..03fc1a2 100644
--- a/src/xenvkbd/hid.c
+++ b/src/xenvkbd/hid.c
@@ -40,6 +40,7 @@
 
 #include "pdo.h"
 #include "hid.h"
+#include "ring.h"
 #include "mrsw.h"
 #include "thread.h"
 #include "vkbd.h"
@@ -51,20 +52,12 @@ struct _XENVKBD_HID_CONTEXT {
     PXENVKBD_PDO                Pdo;
     XENVKBD_MRSW_LOCK           Lock;
     LONG                        References;
+    PXENVKBD_RING               Ring;
     PXENVKBD_FRONTEND           Frontend;
     BOOLEAN                     Enabled;
     ULONG                       Version;
     XENHID_HID_CALLBACK         Callback;
     PVOID                       Argument;
-    XENBUS_DEBUG_INTERFACE      DebugInterface;
-    XENBUS_SUSPEND_INTERFACE    SuspendInterface;
-    PXENBUS_DEBUG_CALLBACK      DebugCallback;
-    PXENBUS_SUSPEND_CALLBACK    SuspendCallbackLate;
-
-    XENVKBD_HID_KEYBOARD        KeyboardReport;
-    XENVKBD_HID_ABSMOUSE        AbsMouseReport;
-    BOOLEAN                     KeyboardPending;
-    BOOLEAN                     AbsMousePending;
 };
 
 #define XENVKBD_VKBD_TAG  'FIV'
@@ -107,68 +100,6 @@ __HidFree(
     __FreePoolWithTag(Buffer, XENVKBD_VKBD_TAG);
 }
 
-static DECLSPEC_NOINLINE VOID
-HidSuspendCallbackLate(
-    IN  PVOID               Argument
-    )
-{
-    PXENVKBD_HID_CONTEXT    Context = Argument;
-    NTSTATUS                status;
-
-    RtlZeroMemory(&Context->KeyboardReport, sizeof(XENVKBD_HID_KEYBOARD));
-    RtlZeroMemory(&Context->AbsMouseReport, sizeof(XENVKBD_HID_ABSMOUSE));
-    Context->KeyboardReport.ReportId = 1;
-    Context->AbsMouseReport.ReportId = 2;
-
-    if (!Context->Enabled)
-        return;
-
-    status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
-    ASSERT(NT_SUCCESS(status));
-}
-
-static DECLSPEC_NOINLINE VOID
-HidDebugCallback(
-    IN  PVOID               Argument,
-    IN  BOOLEAN             Crashing
-    )
-{
-    PXENVKBD_HID_CONTEXT    Context = Argument;
-
-    UNREFERENCED_PARAMETER(Crashing);
-
-    XENBUS_DEBUG(Printf,
-                 &Context->DebugInterface,
-                 "%u 0x%p(0x%p)%s\n",
-                 Context->Version,
-                 Context->Callback,
-                 Context->Argument,
-                 Context->Enabled ? " ENABLED" : "");
-
-    XENBUS_DEBUG(Printf,
-                 &Context->DebugInterface,
-                 "KBD: %02x %02x %02x %02x %02x %02x %02x %02x%s\n",
-                 Context->KeyboardReport.ReportId,
-                 Context->KeyboardReport.Modifiers,
-                 Context->KeyboardReport.Keys[0],
-                 Context->KeyboardReport.Keys[1],
-                 Context->KeyboardReport.Keys[2],
-                 Context->KeyboardReport.Keys[3],
-                 Context->KeyboardReport.Keys[4],
-                 Context->KeyboardReport.Keys[5],
-                 Context->KeyboardPending ? " PENDING" : "");
-
-    XENBUS_DEBUG(Printf,
-                 &Context->DebugInterface,
-                 "MOU: %02x %02x %04x %04x %02x%s\n",
-                 Context->AbsMouseReport.ReportId,
-                 Context->AbsMouseReport.Buttons,
-                 Context->AbsMouseReport.X,
-                 Context->AbsMouseReport.Y,
-                 Context->AbsMouseReport.dZ,
-                 Context->AbsMousePending ? " PENDING" : "");
-}
-
 static NTSTATUS
 HidEnable(
     IN  PINTERFACE          Interface,
@@ -196,35 +127,9 @@ HidEnable(
 
     KeMemoryBarrier();
 
-    status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
     status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
     if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = XENBUS_SUSPEND(Register,
-                            &Context->SuspendInterface,
-                            SUSPEND_CALLBACK_LATE,
-                            HidSuspendCallbackLate,
-                            Context,
-                            &Context->SuspendCallbackLate);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    status = XENBUS_DEBUG(Acquire, &Context->DebugInterface);
-    if (!NT_SUCCESS(status))
-        goto fail4;
-
-    status = XENBUS_DEBUG(Register,
-                          &Context->DebugInterface,
-                          __MODULE__"|DEBUG",
-                          HidDebugCallback,
-                          Context,
-                          &Context->DebugCallback);
-    if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail1;
 
 done:
     ASSERT(Exclusive);
@@ -234,32 +139,6 @@ done:
 
     return STATUS_SUCCESS;
 
-fail5:
-    Error("fail5\n");
-
-    XENBUS_DEBUG(Release, &Context->DebugInterface);
-
-fail4:
-    Error("fail4\n");
-
-    XENBUS_SUSPEND(Deregister,
-                   &Context->SuspendInterface,
-                   Context->SuspendCallbackLate);
-    Context->SuspendCallbackLate = NULL;
-
-fail3:
-    Error("fail3\n");
-
-    (VOID) FrontendSetState(Context->Frontend, FRONTEND_CONNECTED);
-
-    ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE);
-    Exclusive = FALSE;
-
-fail2:
-    Error("fail2\n");
-
-    XENBUS_SUSPEND(Release, &Context->SuspendInterface);
-
 fail1:
     Error("fail1 (%08x)\n", status);
 
@@ -299,24 +178,10 @@ HidDisable(
 
     KeMemoryBarrier();
 
-    XENBUS_DEBUG(Deregister,
-                 &Context->DebugInterface,
-                 Context->DebugCallback);
-    Context->DebugCallback = NULL;
-
-    XENBUS_DEBUG(Release, &Context->DebugInterface);
-
-    XENBUS_SUSPEND(Deregister,
-                   &Context->SuspendInterface,
-                   Context->SuspendCallbackLate);
-    Context->SuspendCallbackLate = NULL;
-
     (VOID) FrontendSetState(Context->Frontend, FRONTEND_CONNECTED);
 
     ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE);
 
-    XENBUS_SUSPEND(Release, &Context->SuspendInterface);
-
     Context->Argument = NULL;
     Context->Callback = NULL;
 
@@ -467,8 +332,13 @@ HidGetIndexedString(
     Trace("=====>\n");
     AcquireMrswLockShared(&Context->Lock);
 
+    status = STATUS_DEVICE_NOT_READY;
+    if (!Context->Enabled)
+        goto done;
+
     status = STATUS_NOT_SUPPORTED;
-  
+
+done:
     ReleaseMrswLockShared(&Context->Lock);
     Trace("<=====\n");
 
@@ -494,8 +364,13 @@ HidGetFeature(
     Trace("=====>\n");
     AcquireMrswLockShared(&Context->Lock);
 
+    status = STATUS_DEVICE_NOT_READY;
+    if (!Context->Enabled)
+        goto done;
+
     status = STATUS_NOT_SUPPORTED;
-  
+
+done:
     ReleaseMrswLockShared(&Context->Lock);
     Trace("<=====\n");
 
@@ -520,8 +395,13 @@ HidSetFeature(
     Trace("=====>\n");
     AcquireMrswLockShared(&Context->Lock);
 
+    status = STATUS_DEVICE_NOT_READY;
+    if (!Context->Enabled)
+        goto done;
+
     status = STATUS_NOT_SUPPORTED;
-  
+
+done:
     ReleaseMrswLockShared(&Context->Lock);
     Trace("<=====\n");
 
@@ -546,32 +426,20 @@ HidGetInputReport(
     Trace("=====>\n");
     AcquireMrswLockShared(&Context->Lock);
 
-    switch (ReportId) {
-    case 1:
-        status = HidCopyBuffer(Buffer,
-                               Length,
-                               &Context->KeyboardReport,
-                               sizeof(XENVKBD_HID_KEYBOARD),
-                               Returned);
-        break;
-    case 2:
-        status = HidCopyBuffer(Buffer,
-                               Length,
-                               &Context->AbsMouseReport,
-                               sizeof(XENVKBD_HID_ABSMOUSE),
-                               Returned);
-        break;
-    default:
-        status = STATUS_NOT_SUPPORTED;
-        break;
-    }
-  
+    status = STATUS_DEVICE_NOT_READY;
+    if (!Context->Enabled)
+        goto done;
+
+    status = RingGetInputReport(Context->Ring,
+                                ReportId,
+                                Buffer,
+                                Length,
+                                Returned);
+
+done:
     ReleaseMrswLockShared(&Context->Lock);
     Trace("<=====\n");
 
-    UNREFERENCED_PARAMETER(ReportId);
-    UNREFERENCED_PARAMETER(Buffer);
-    UNREFERENCED_PARAMETER(Length);
     return status;
 }
 
@@ -589,8 +457,13 @@ HidSetOutputReport(
     Trace("=====>\n");
     AcquireMrswLockShared(&Context->Lock);
 
+    status = STATUS_DEVICE_NOT_READY;
+    if (!Context->Enabled)
+        goto done;
+
     status = STATUS_NOT_SUPPORTED;
-  
+
+done:
     ReleaseMrswLockShared(&Context->Lock);
     Trace("<=====\n");
 
@@ -600,23 +473,6 @@ HidSetOutputReport(
     return status;
 }
 
-static BOOLEAN
-HidSendReadReport(
-    IN  PXENVKBD_HID_CONTEXT    Context,
-    IN  PVOID                   Buffer,
-    IN  ULONG                   Length
-    )
-{
-    if (!Context->Enabled)
-        return TRUE; // flag as pending
-
-    // Callback returns TRUE on success, FALSE when Irp could not be completed
-    // Invert the result to indicate Pending state
-    return !Context->Callback(Context->Argument,
-                              Buffer,
-                              Length);
-}
-
 static VOID
 HidReadReport(
     IN  PINTERFACE          Interface
@@ -626,15 +482,8 @@ HidReadReport(
 
     AcquireMrswLockShared(&Context->Lock);
 
-    // Check for pending reports, push 1 pending report to subscriber
-    if (Context->KeyboardPending)
-        Context->KeyboardPending = HidSendReadReport(Context,
-                                                     &Context->KeyboardReport,
-                                                     
sizeof(XENVKBD_HID_KEYBOARD));
-    else if (Context->AbsMousePending)
-        Context->AbsMousePending = HidSendReadReport(Context,
-                                                     &Context->AbsMouseReport,
-                                                     
sizeof(XENVKBD_HID_ABSMOUSE));
+    if (Context->Enabled)
+        RingReadReport(Context->Ring);
 
     ReleaseMrswLockShared(&Context->Lock);
 }
@@ -653,8 +502,13 @@ HidWriteReport(
     Trace("=====>\n");
     AcquireMrswLockShared(&Context->Lock);
 
+    status = STATUS_DEVICE_NOT_READY;
+    if (!Context->Enabled)
+        goto done;
+
     status = STATUS_NOT_SUPPORTED;
-  
+
+done:
     ReleaseMrswLockShared(&Context->Lock);
     Trace("<=====\n");
 
@@ -680,6 +534,7 @@ HidAcquire(
     Trace("====>\n");
 
     Context->Frontend = PdoGetFrontend(Context->Pdo);
+    Context->Ring = FrontendGetRing(Context->Frontend);
     Context->Version = Interface->Version;
 
     Trace("<====\n");
@@ -709,6 +564,7 @@ HidRelease(
 
     Context->Version = 0;
     Context->Frontend = NULL;
+    Context->Ring = NULL;
 
     Trace("<====\n");
 
@@ -753,12 +609,7 @@ HidInitialize(
 
     InitializeMrswLock(&(*Context)->Lock);
 
-    FdoGetDebugInterface(PdoGetFdo(Pdo),&(*Context)->DebugInterface);
-    FdoGetSuspendInterface(PdoGetFdo(Pdo),&(*Context)->SuspendInterface);
-
     (*Context)->Pdo = Pdo;
-    (*Context)->KeyboardReport.ReportId = 1;
-    (*Context)->AbsMouseReport.ReportId = 2;
 
     Trace("<====\n");
 
@@ -813,19 +664,9 @@ HidTeardown(
 {
     Trace("====>\n");
 
-    RtlZeroMemory(&Context->KeyboardReport, sizeof(XENVKBD_HID_KEYBOARD));
-    RtlZeroMemory(&Context->AbsMouseReport, sizeof(XENVKBD_HID_ABSMOUSE));
-    Context->KeyboardPending = FALSE;
-    Context->AbsMousePending = FALSE;
-
     Context->Pdo = NULL;
     Context->Version = 0;
 
-    RtlZeroMemory(&Context->SuspendInterface,
-                  sizeof (XENBUS_SUSPEND_INTERFACE));
-    RtlZeroMemory(&Context->DebugInterface,
-                  sizeof (XENBUS_DEBUG_INTERFACE));
-
     RtlZeroMemory(&Context->Lock, sizeof (XENVKBD_MRSW_LOCK));
 
     ASSERT(IsZeroMemory(Context, sizeof (XENVKBD_HID_CONTEXT)));
@@ -834,148 +675,19 @@ HidTeardown(
     Trace("<====\n");
 }
 
-static FORCEINLINE LONG
-Constrain(
-    IN  LONG    Value,
-    IN  LONG    Min,
-    IN  LONG    Max
-    )
-{
-    if (Value < Min)
-        return Min;
-    if (Value > Max)
-        return Max;
-    return Value;
-}
-
-static FORCEINLINE UCHAR
-SetBit(
-    IN  UCHAR   Value,
-    IN  UCHAR   BitIdx,
-    IN  BOOLEAN Pressed
-    )
-{
-    if (Pressed) {
-        return Value | (1 << BitIdx);
-    } else {
-        return Value & ~(1 << BitIdx);
-    }
-}
-
-static FORCEINLINE VOID
-SetArray(
-    IN  PUCHAR  Array,
-    IN  ULONG   Size,
-    IN  UCHAR   Value,
-    IN  BOOLEAN Pressed
-    )
-{
-    ULONG       Idx;
-    if (Pressed) {
-        for (Idx = 0; Idx < Size; ++Idx) {
-            if (Array[Idx] == Value)
-                break;
-            if (Array[Idx] != 0)
-                continue;
-            Array[Idx] = Value;
-            break;
-        }
-    } else {
-        for (Idx = 0; Idx < Size; ++Idx) {
-            if (Array[Idx] == 0)
-                break;
-            if (Array[Idx] != Value)
-                continue;
-            for (; Idx < Size - 1; ++Idx)
-                Array[Idx] = Array[Idx + 1];
-            Array[Size - 1] = 0;
-            break;
-        }
-    }
-}
-
-static FORCEINLINE USHORT
-KeyCodeToUsage(
-    IN  ULONG   KeyCode
-    )
-{
-    if (KeyCode < sizeof(VkbdKeyCodeToUsage)/sizeof(VkbdKeyCodeToUsage[0]))
-        return VkbdKeyCodeToUsage[KeyCode];
-    return 0;
-}
-
-VOID
-HidEventMotion(
-    IN  PXENVKBD_HID_CONTEXT    Context,
-    IN  LONG                    dX,
-    IN  LONG                    dY,
-    IN  LONG                    dZ
-    )
-{
-    Context->AbsMouseReport.X = (USHORT)Constrain(Context->AbsMouseReport.X + 
dX, 0, 32767);
-    Context->AbsMouseReport.Y = (USHORT)Constrain(Context->AbsMouseReport.Y + 
dY, 0, 32767);
-    Context->AbsMouseReport.dZ = -(CHAR)Constrain(dZ, -127, 127);
-
-    Context->AbsMousePending = HidSendReadReport(Context,
-                                                 &Context->AbsMouseReport,
-                                                 sizeof(XENVKBD_HID_ABSMOUSE));
-}
-
-VOID
-HidEventKeypress(
-    IN  PXENVKBD_HID_CONTEXT    Context,
-    IN  ULONG                   KeyCode,
-    IN  BOOLEAN                 Pressed
-    )
-{
-    if (KeyCode >= 0x110 && KeyCode <= 0x114) {
-        // Mouse Buttons
-        Context->AbsMouseReport.Buttons = 
SetBit(Context->AbsMouseReport.Buttons,
-                                                 (UCHAR)(KeyCode - 0x110),
-                                                 Pressed);
-
-        Context->AbsMousePending = HidSendReadReport(Context,
-                                                    &Context->AbsMouseReport,
-                                                    
sizeof(XENVKBD_HID_ABSMOUSE));
-
-    } else {
-        // map KeyCode to Usage
-        USHORT  Usage = KeyCodeToUsage(KeyCode);
-        if (Usage == 0)
-            return; // non-standard key
-
-        if (Usage >= 0xE0 && Usage <= 0xE7) {
-            // Modifier
-            Context->KeyboardReport.Modifiers = 
SetBit(Context->KeyboardReport.Modifiers,
-                                                       (UCHAR)(Usage - 0xE0),
-                                                       Pressed);
-        } else {
-            // Standard Key
-            SetArray(Context->KeyboardReport.Keys,
-                     6,
-                     (UCHAR)Usage,
-                     Pressed);
-        }
-        Context->KeyboardPending = HidSendReadReport(Context,
-                                                    &Context->KeyboardReport,
-                                                    
sizeof(XENVKBD_HID_KEYBOARD));
-
-    }
-}
-
-VOID
-HidEventPosition(
+BOOLEAN
+HidSendReadReport(
     IN  PXENVKBD_HID_CONTEXT    Context,
-    IN  ULONG                   X,
-    IN  ULONG                   Y,
-    IN  LONG                    dZ
+    IN  PVOID                   Buffer,
+    IN  ULONG                   Length
     )
 {
-    Context->AbsMouseReport.X = (USHORT)Constrain(X, 0, 32767);
-    Context->AbsMouseReport.Y = (USHORT)Constrain(Y, 0, 32767);
-    Context->AbsMouseReport.dZ = -(CHAR)Constrain(dZ, -127, 127);
+    if (!Context->Enabled)
+        return TRUE; // flag as pending
 
-    Context->AbsMousePending = HidSendReadReport(Context,
-                                                 &Context->AbsMouseReport,
-                                                 sizeof(XENVKBD_HID_ABSMOUSE));
+    // Callback returns TRUE on success, FALSE when Irp could not be completed
+    // Invert the result to indicate Pending state
+    return !Context->Callback(Context->Argument,
+                              Buffer,
+                              Length);
 }
diff --git a/src/xenvkbd/hid.h b/src/xenvkbd/hid.h
index ec38e28..116f749 100644
--- a/src/xenvkbd/hid.h
+++ b/src/xenvkbd/hid.h
@@ -62,27 +62,11 @@ HidTeardown(
 
 // CALLBACKS
 
-extern VOID
-HidEventMotion(
-    IN  PXENVKBD_HID_CONTEXT    Context,
-    IN  LONG                    dX,
-    IN  LONG                    dY,
-    IN  LONG                    dZ
-    );
-
-extern VOID
-HidEventKeypress(
-    IN  PXENVKBD_HID_CONTEXT    Context,
-    IN  ULONG                   KeyCode,
-    IN  BOOLEAN                 Pressed
-    );
-
-extern VOID
-HidEventPosition(
+extern BOOLEAN
+HidSendReadReport(
     IN  PXENVKBD_HID_CONTEXT    Context,
-    IN  ULONG                   X,
-    IN  ULONG                   Y,
-    IN  LONG                    dZ
+    IN  PVOID                   Buffer,
+    IN  ULONG                   Length
     );
 
 #endif  // _XENVKBD_VKBD_H
diff --git a/src/xenvkbd/pdo.h b/src/xenvkbd/pdo.h
index a23811e..5e68a86 100644
--- a/src/xenvkbd/pdo.h
+++ b/src/xenvkbd/pdo.h
@@ -147,36 +147,6 @@ PdoGetFrontend(
     IN  PXENVKBD_PDO    Pdo
     );
 
-extern PXENBUS_EVTCHN_INTERFACE
-PdoGetEvtchnInterface(
-    IN  PXENVKBD_PDO    Pdo
-    );
-
-extern PXENBUS_DEBUG_INTERFACE
-PdoGetDebugInterface(
-    IN  PXENVKBD_PDO    Pdo
-    );
-
-extern PXENBUS_STORE_INTERFACE
-PdoGetStoreInterface(
-    IN  PXENVKBD_PDO    Pdo
-    );
-
-extern PXENBUS_CACHE_INTERFACE
-PdoGetCacheInterface(
-    IN  PXENVKBD_PDO    Pdo
-    );
-
-extern PXENBUS_GNTTAB_INTERFACE
-PdoGetGnttabInterface(
-    IN  PXENVKBD_PDO    Pdo
-    );
-
-extern PXENBUS_SUSPEND_INTERFACE
-PdoGetSuspendInterface(
-    IN  PXENVKBD_PDO    Pdo
-    );
-
 #include "hid.h"
 
 extern PXENVKBD_HID_CONTEXT
@@ -184,11 +154,6 @@ PdoGetHidContext(
     IN  PXENVKBD_PDO    Pdo
     );
 
-extern PXENHID_HID_INTERFACE
-PdoGetHidInterface(
-    IN  PXENVKBD_PDO    Pdo
-    );
-
 extern NTSTATUS
 PdoDispatch(
     IN  PXENVKBD_PDO    Pdo,
diff --git a/src/xenvkbd/ring.c b/src/xenvkbd/ring.c
index dd15807..da1bd17 100644
--- a/src/xenvkbd/ring.c
+++ b/src/xenvkbd/ring.c
@@ -46,6 +46,7 @@
 #include "frontend.h"
 #include "ring.h"
 #include "hid.h"
+#include "vkbd.h"
 #include "thread.h"
 #include "registry.h"
 #include "dbg_print.h"
@@ -77,6 +78,11 @@ struct _XENVKBD_RING {
     BOOLEAN                 Connected;
     BOOLEAN                 Enabled;
     BOOLEAN                 AbsPointer;
+
+    XENVKBD_HID_KEYBOARD    KeyboardReport;
+    XENVKBD_HID_ABSMOUSE    AbsMouseReport;
+    BOOLEAN                 KeyboardPending;
+    BOOLEAN                 AbsMousePending;
 };
 
 #define XENVKBD_RING_TAG    'gniR'
@@ -97,6 +103,174 @@ __RingFree(
     __FreePoolWithTag(Buffer, XENVKBD_RING_TAG);
 }
 
+static FORCEINLINE NTSTATUS
+__RingCopyBuffer(
+    IN  PVOID       Buffer,
+    IN  ULONG       Length,
+    IN  const VOID  *Source,
+    IN  ULONG       SourceLength,
+    OUT PULONG      Returned
+    )
+{
+    if (Buffer == NULL)
+        return STATUS_INVALID_PARAMETER;
+    if (Length < SourceLength)
+        return STATUS_NO_MEMORY;
+
+    RtlCopyMemory(Buffer,
+                  Source,
+                  SourceLength);
+    if (Returned)
+        *Returned = SourceLength;
+    return STATUS_SUCCESS;
+}
+
+static FORCEINLINE LONG
+Constrain(
+    IN  LONG    Value,
+    IN  LONG    Min,
+    IN  LONG    Max
+    )
+{
+    if (Value < Min)
+        return Min;
+    if (Value > Max)
+        return Max;
+    return Value;
+}
+
+static FORCEINLINE UCHAR
+SetBit(
+    IN  UCHAR   Value,
+    IN  UCHAR   BitIdx,
+    IN  BOOLEAN Pressed
+    )
+{
+    if (Pressed) {
+        return Value | (1 << BitIdx);
+    } else {
+        return Value & ~(1 << BitIdx);
+    }
+}
+
+static FORCEINLINE VOID
+SetArray(
+    IN  PUCHAR  Array,
+    IN  ULONG   Size,
+    IN  UCHAR   Value,
+    IN  BOOLEAN Pressed
+    )
+{
+    ULONG       Idx;
+    if (Pressed) {
+        for (Idx = 0; Idx < Size; ++Idx) {
+            if (Array[Idx] == Value)
+                break;
+            if (Array[Idx] != 0)
+                continue;
+            Array[Idx] = Value;
+            break;
+        }
+    } else {
+        for (Idx = 0; Idx < Size; ++Idx) {
+            if (Array[Idx] == 0)
+                break;
+            if (Array[Idx] != Value)
+                continue;
+            for (; Idx < Size - 1; ++Idx)
+                Array[Idx] = Array[Idx + 1];
+            Array[Size - 1] = 0;
+            break;
+        }
+    }
+}
+
+static FORCEINLINE USHORT
+KeyCodeToUsage(
+    IN  ULONG   KeyCode
+    )
+{
+    if (KeyCode < sizeof(VkbdKeyCodeToUsage)/sizeof(VkbdKeyCodeToUsage[0]))
+        return VkbdKeyCodeToUsage[KeyCode];
+    return 0;
+}
+
+static FORCEINLINE VOID
+__RingEventMotion(
+    IN  PXENVKBD_RING   Ring,
+    IN  LONG            dX,
+    IN  LONG            dY,
+    IN  LONG            dZ
+    )
+{
+    Ring->AbsMouseReport.X = (USHORT)Constrain(Ring->AbsMouseReport.X + dX, 0, 
32767);
+    Ring->AbsMouseReport.Y = (USHORT)Constrain(Ring->AbsMouseReport.Y + dY, 0, 
32767);
+    Ring->AbsMouseReport.dZ = -(CHAR)Constrain(dZ, -127, 127);
+
+    Ring->AbsMousePending = HidSendReadReport(Ring->Hid,
+                                              &Ring->AbsMouseReport,
+                                              sizeof(XENVKBD_HID_ABSMOUSE));
+}
+
+static FORCEINLINE VOID
+__RingEventKeypress(
+    IN  PXENVKBD_RING   Ring,
+    IN  ULONG           KeyCode,
+    IN  BOOLEAN         Pressed
+    )
+{
+    if (KeyCode >= 0x110 && KeyCode <= 0x114) {
+        // Mouse Buttons
+        Ring->AbsMouseReport.Buttons = SetBit(Ring->AbsMouseReport.Buttons,
+                                              (UCHAR)(KeyCode - 0x110),
+                                              Pressed);
+
+        Ring->AbsMousePending = HidSendReadReport(Ring->Hid,
+                                                  &Ring->AbsMouseReport,
+                                                  
sizeof(XENVKBD_HID_ABSMOUSE));
+
+    } else {
+        // map KeyCode to Usage
+        USHORT  Usage = KeyCodeToUsage(KeyCode);
+        if (Usage == 0)
+            return; // non-standard key
+
+        if (Usage >= 0xE0 && Usage <= 0xE7) {
+            // Modifier
+            Ring->KeyboardReport.Modifiers = 
SetBit(Ring->KeyboardReport.Modifiers,
+                                                    (UCHAR)(Usage - 0xE0),
+                                                    Pressed);
+        } else {
+            // Standard Key
+            SetArray(Ring->KeyboardReport.Keys,
+                     6,
+                     (UCHAR)Usage,
+                     Pressed);
+        }
+        Ring->KeyboardPending = HidSendReadReport(Ring->Hid,
+                                                  &Ring->KeyboardReport,
+                                                  
sizeof(XENVKBD_HID_KEYBOARD));
+
+    }
+}
+
+static FORCEINLINE VOID
+__RingEventPosition(
+    IN  PXENVKBD_RING   Ring,
+    IN  ULONG           X,
+    IN  ULONG           Y,
+    IN  LONG            dZ
+    )
+{
+    Ring->AbsMouseReport.X = (USHORT)Constrain(X, 0, 32767);
+    Ring->AbsMouseReport.Y = (USHORT)Constrain(Y, 0, 32767);
+    Ring->AbsMouseReport.dZ = -(CHAR)Constrain(dZ, -127, 127);
+
+    Ring->AbsMousePending = HidSendReadReport(Ring->Hid,
+                                              &Ring->AbsMouseReport,
+                                              sizeof(XENVKBD_HID_ABSMOUSE));
+}
+
 __drv_functionClass(KDEFERRED_ROUTINE)
 __drv_maxIRQL(DISPATCH_LEVEL)
 __drv_minIRQL(DISPATCH_LEVEL)
@@ -140,21 +314,21 @@ RingDpc(
 
             switch (in_evt->type) {
             case XENKBD_TYPE_MOTION:
-                HidEventMotion(Ring->Hid,
-                               in_evt->motion.rel_x,
-                               in_evt->motion.rel_y,
-                               in_evt->motion.rel_z);
+                __RingEventMotion(Ring,
+                                  in_evt->motion.rel_x,
+                                  in_evt->motion.rel_y,
+                                  in_evt->motion.rel_z);
                 break;
             case XENKBD_TYPE_KEY:
-                HidEventKeypress(Ring->Hid,
-                                 in_evt->key.keycode,
-                                 in_evt->key.pressed);                        
+                __RingEventKeypress(Ring,
+                                    in_evt->key.keycode,
+                                    in_evt->key.pressed);
                 break;
             case XENKBD_TYPE_POS:
-                HidEventPosition(Ring->Hid,
-                                 in_evt->pos.abs_x,
-                                 in_evt->pos.abs_y,
-                                 in_evt->pos.rel_z);
+                __RingEventPosition(Ring,
+                                    in_evt->pos.abs_x,
+                                    in_evt->pos.abs_y,
+                                    in_evt->pos.rel_z);
                 break;
             case XENKBD_TYPE_MTOUCH:
                 Trace("MTOUCH: %u %u %u %u\n",
@@ -237,6 +411,29 @@ RingDebugCallback(
                  "0x%p [%s]\n",
                  Ring,
                  (Ring->Enabled) ? "ENABLED" : "DISABLED");
+
+    XENBUS_DEBUG(Printf,
+                 &Ring->DebugInterface,
+                 "KBD: %02x %02x %02x %02x %02x %02x %02x %02x%s\n",
+                 Ring->KeyboardReport.ReportId,
+                 Ring->KeyboardReport.Modifiers,
+                 Ring->KeyboardReport.Keys[0],
+                 Ring->KeyboardReport.Keys[1],
+                 Ring->KeyboardReport.Keys[2],
+                 Ring->KeyboardReport.Keys[3],
+                 Ring->KeyboardReport.Keys[4],
+                 Ring->KeyboardReport.Keys[5],
+                 Ring->KeyboardPending ? " PENDING" : "");
+
+    XENBUS_DEBUG(Printf,
+                 &Ring->DebugInterface,
+                 "MOU: %02x %02x %04x %04x %02x%s\n",
+                 Ring->AbsMouseReport.ReportId,
+                 Ring->AbsMouseReport.Buttons,
+                 Ring->AbsMouseReport.X,
+                 Ring->AbsMouseReport.Y,
+                 Ring->AbsMouseReport.dZ,
+                 Ring->AbsMousePending ? " PENDING" : "");
 }
 
 NTSTATUS
@@ -341,6 +538,8 @@ RingConnect(
     if (!NT_SUCCESS(status))
         goto fail5;
 
+    Ring->KeyboardReport.ReportId = 1;
+    Ring->AbsMouseReport.ReportId = 2;
     RingReadFeatures(Ring);
 
     Ring->Mdl = __AllocatePage();
@@ -589,6 +788,13 @@ RingDisconnect(
     __FreePage(Ring->Mdl);
     Ring->Mdl = NULL;
 
+    RtlZeroMemory(&Ring->KeyboardReport,
+                  sizeof(XENVKBD_HID_KEYBOARD));
+    RtlZeroMemory(&Ring->AbsMouseReport,
+                  sizeof(XENVKBD_HID_ABSMOUSE));
+    Ring->KeyboardPending = FALSE;
+    Ring->AbsMousePending = FALSE;
+
     XENBUS_GNTTAB(DestroyCache,
                   &Ring->GnttabInterface,
                   Ring->GnttabCache);
@@ -645,3 +851,46 @@ RingNotify(
     if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL))
         Ring->Dpcs++;
 }
+
+NTSTATUS
+RingGetInputReport(
+    IN  PXENVKBD_RING   Ring,
+    IN  ULONG           ReportId,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    )
+{
+    switch (ReportId) {
+    case 1:
+        return __RingCopyBuffer(Buffer,
+                                Length,
+                                &Ring->KeyboardReport,
+                                sizeof(XENVKBD_HID_KEYBOARD),
+                                Returned);
+    case 2:
+        return __RingCopyBuffer(Buffer,
+                                Length,
+                                &Ring->AbsMouseReport,
+                                sizeof(XENVKBD_HID_ABSMOUSE),
+                                Returned);
+    default:
+        return STATUS_NOT_SUPPORTED;
+    }
+}
+
+VOID
+RingReadReport(
+    IN  PXENVKBD_RING   Ring
+    )
+{
+    // Check for pending reports, push 1 pending report to subscriber
+    if (Ring->KeyboardPending)
+        Ring->KeyboardPending = HidSendReadReport(Ring->Hid,
+                                                  &Ring->KeyboardReport,
+                                                  
sizeof(XENVKBD_HID_KEYBOARD));
+    else if (Ring->AbsMousePending)
+        Ring->AbsMousePending = HidSendReadReport(Ring->Hid,
+                                                  &Ring->AbsMouseReport,
+                                                  
sizeof(XENVKBD_HID_ABSMOUSE));
+}
diff --git a/src/xenvkbd/ring.h b/src/xenvkbd/ring.h
index 09d1f8e..bfc6c4f 100644
--- a/src/xenvkbd/ring.h
+++ b/src/xenvkbd/ring.h
@@ -82,4 +82,18 @@ RingNotify(
     IN  PXENVKBD_RING   Ring
     );
 
+extern NTSTATUS
+RingGetInputReport(
+    IN  PXENVKBD_RING   Ring,
+    IN  ULONG           ReportId,
+    IN  PVOID           Buffer,
+    IN  ULONG           Length,
+    OUT PULONG          Returned
+    );
+
+extern VOID
+RingReadReport(
+    IN  PXENVKBD_RING   Ring
+    );
+
 #endif  // _XENVKBD_RING_H
-- 
2.8.3


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.