[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH 2/4] xenvkbd: Move input reports to Ring.c
> -----Original Message----- > From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On > Behalf Of owen.smith@xxxxxxxxxx > Sent: 07 June 2017 16:52 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Owen Smith <owen.smith@xxxxxxxxxx> > Subject: [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> Acked-by: Paul Durrant <paul.durrant@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 _______________________________________________ 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 |