|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |