Add Green driver, that emulates a VT100 compatible server. Input won't work as long as we don't have a kdbclass driver. Added: trunk/reactos/drivers/dd/green/ Added: trunk/reactos/drivers/dd/green/createclose.c Added: trunk/reactos/drivers/dd/green/dispatch.c Added: trunk/reactos/drivers/dd/green/green.c Added: trunk/reactos/drivers/dd/green/green.h Added: trunk/reactos/drivers/dd/green/green.rc Added: trunk/reactos/drivers/dd/green/keyboard.c Added: trunk/reactos/drivers/dd/green/makefile Added: trunk/reactos/drivers/dd/green/misc.c Added: trunk/reactos/drivers/dd/green/pnp.c Added: trunk/reactos/drivers/dd/green/screen.c _____
Added: trunk/reactos/drivers/dd/green/createclose.c --- trunk/reactos/drivers/dd/green/createclose.c 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/createclose.c 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,38 @@
+/* $Id: + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VT100 emulator + * FILE: drivers/dd/green/createclose.c + * PURPOSE: IRP_MJ_CREATE, IRP_MJ_CLOSE and IRP_MJ_CLEANUP operations + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) + */ + +//#define NDEBUG +#include "green.h" + +NTSTATUS STDCALL +GreenCreate( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("Green: IRP_MJ_CREATE\n"); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} + +NTSTATUS STDCALL +GreenClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + DPRINT("Green: IRP_MJ_CLOSE\n"); + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +} Property changes on: trunk/reactos/drivers/dd/green/createclose.c ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/dispatch.c --- trunk/reactos/drivers/dd/green/dispatch.c 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/dispatch.c 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,65 @@
+/* $Id: + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VT100 emulator + * FILE: drivers/dd/green/dispatch.c + * PURPOSE: Dispatch routines + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) + */ + +#define NDEBUG +#include "green.h" + +NTSTATUS STDCALL +GreenDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + ULONG MajorFunction; + GREEN_DEVICE_TYPE DeviceType; + ULONG_PTR Information; + NTSTATUS Status; + + MajorFunction = IoGetCurrentIrpStackLocation(Irp)->MajorFunction; + DeviceType = ((PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Type; + + Information = Irp->IoStatus.Information; + Status = Irp->IoStatus.Status; + + DPRINT("Green: Dispatching major function 0x%lx, DeviceType %d\n", + MajorFunction, DeviceType); + + if (MajorFunction == IRP_MJ_CREATE && DeviceType == Green) + return GreenCreate(DeviceObject, Irp); + else if (MajorFunction == IRP_MJ_CLOSE && DeviceType == Green) + return GreenClose(DeviceObject, Irp); + else if (MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && DeviceType == Green) + { + return KeyboardInternalDeviceControl( + ((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Keyboard, + Irp); + } + else if (MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL && DeviceType == Keyboard) + return KeyboardInternalDeviceControl(DeviceObject, Irp); + else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == Green) + { + return ScreenDeviceControl( + ((PGREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->Screen, + Irp); + } + else if (MajorFunction == IRP_MJ_DEVICE_CONTROL && DeviceType == Screen) + return ScreenDeviceControl(DeviceObject, Irp); + else if (MajorFunction == IRP_MJ_WRITE && DeviceType == Screen) + return ScreenWrite(DeviceObject, Irp); + else + { + DPRINT1("Green: unknown combination: MajorFunction 0x%lx, DeviceType %d\n", + MajorFunction, DeviceType); + } + + Irp->IoStatus.Information = Information; + Irp->IoStatus.Status = Status; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + return Status; +} Property changes on: trunk/reactos/drivers/dd/green/dispatch.c ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/green.c --- trunk/reactos/drivers/dd/green/green.c 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/green.c 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,44 @@
+/* $Id: + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VT100 emulator + * FILE: drivers/dd/green/green.c + * PURPOSE: Driver entry point + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) + */ + +//#define NDEBUG +#include "green.h" + +VOID STDCALL +DriverUnload(IN PDRIVER_OBJECT DriverObject) +{ + // nothing to do here yet +} + +/* + * Standard DriverEntry method. + */ +NTSTATUS STDCALL +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegPath) +{ + ULONG i; + + DriverObject->DriverUnload = DriverUnload; + DriverObject->DriverExtension->AddDevice = GreenAddDevice; + + for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) + DriverObject->MajorFunction[i] = GreenDispatch; + + /* keyboard only */ + //DriverObject->DriverStartIo = GreenStartIo; + + /* keyboard and screen */ + DriverObject->MajorFunction[IRP_MJ_CREATE] = GreenCreate; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = GreenClose; + + return STATUS_SUCCESS; +} Property changes on: trunk/reactos/drivers/dd/green/green.c ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/green.h --- trunk/reactos/drivers/dd/green/green.h 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/green.h 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,179 @@
+#if defined(__GNUC__) + #include <ddk/ntddk.h> + #include <ddk/ntddser.h> + #include <ntos/halfuncs.h> + #include <ddk/ntddblue.h> + #include <ddk/ntddkbd.h> /* should be in kbdmou.h */ + + #include <debug.h> + + /* FIXME: should be in kbdmou.h */ + typedef struct _CONNECT_DATA { + PDEVICE_OBJECT ClassDeviceObject; + PVOID ClassService; + } CONNECT_DATA, *PCONNECT_DATA; + + /* FIXME: should be in kbdmou.h */ + #define IOCTL_INTERNAL_KEYBOARD_CONNECT \ + CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS) + + NTSTATUS STDCALL + ObReferenceObjectByName(PUNICODE_STRING ObjectPath, + ULONG Attributes, + PACCESS_STATE PassedAccessState, + ACCESS_MASK DesiredAccess, + POBJECT_TYPE ObjectType, + KPROCESSOR_MODE AccessMode, + PVOID ParseContext, + PVOID* ObjectPtr); + + /* FIXME: should be in kbdmou.h */ + typedef VOID (*PSERVICE_CALLBACK_ROUTINE)(PDEVICE_OBJECT, PKEYBOARD_INPUT_DATA, PKEYBOARD_INPUT_DATA, PULONG); + + typedef struct _CLASS_INFORMATION + { + PDEVICE_OBJECT DeviceObject; + PVOID CallBack; + } CLASS_INFORMATION, *PCLASS_INFORMATION; + + #define KEYBOARD_BUFFER_SIZE 100 + +#elif defined(_MSC_VER) + #include <ntddk.h> + #include <ntddser.h> + #include <kbdmou.h> + + #define STDCALL + + #define DPRINT1 DbgPrint("(%s:%d) ", __FILE__, __LINE__), DbgPrint + #define CHECKPOINT1 DbgPrint("(%s:%d)\n", __FILE__, __LINE__) + #define DPRINT DPRINT1 + #define CHECKPOINT CHECKPOINT1 +#else + #error Unknown compiler! +#endif + +typedef enum +{ + Green, + Screen, + Keyboard +} GREEN_DEVICE_TYPE; + +typedef struct _COMMON_DEVICE_EXTENSION +{ + GREEN_DEVICE_TYPE Type; +} COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION; + +typedef struct _KEYBOARD_DEVICE_EXTENSION +{ + COMMON_DEVICE_EXTENSION Common; + PDEVICE_OBJECT Green; + + CLASS_INFORMATION ClassInformation; + HANDLE WorkerThreadHandle; + KDPC KeyboardDpc; + + ULONG ActiveQueue; + ULONG InputDataCount[2]; + KEYBOARD_INPUT_DATA KeyboardInputData[2][KEYBOARD_BUFFER_SIZE]; +} KEYBOARD_DEVICE_EXTENSION, *PKEYBOARD_DEVICE_EXTENSION; + +typedef struct _SCREEN_DEVICE_EXTENSION +{ + COMMON_DEVICE_EXTENSION Common; + PDEVICE_OBJECT Green; + + PUCHAR VideoMemory; /* Pointer to video memory */ + USHORT CharAttribute; /* Current color attribute */ + ULONG Mode; + UCHAR ScanLines; /* Height of a text line */ + UCHAR Rows; /* Number of rows */ + UCHAR Columns; /* Number of columns */ + UCHAR TabWidth; + + ULONG LogicalOffset; /* Position of the cursor */ + + UCHAR SendBuffer[1024]; + ULONG SendBufferPosition; +} SCREEN_DEVICE_EXTENSION, *PSCREEN_DEVICE_EXTENSION; + +typedef struct _GREEN_DEVICE_EXTENSION +{ + COMMON_DEVICE_EXTENSION Common; + PDEVICE_OBJECT Serial; + + PDEVICE_OBJECT LowerDevice; + ULONG BaudRate; + SERIAL_LINE_CONTROL LineControl; + SERIAL_TIMEOUTS Timeouts; + + PDEVICE_OBJECT Keyboard; + PDEVICE_OBJECT Screen; +} GREEN_DEVICE_EXTENSION, *PGREEN_DEVICE_EXTENSION; + +/************************************ createclose.c */ + +NTSTATUS STDCALL +GreenCreate( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS STDCALL +GreenClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/************************************ dispatch.c */ + +NTSTATUS STDCALL +GreenDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/************************************ keyboard.c */ + +NTSTATUS +KeyboardInitialize( + IN PDRIVER_OBJECT DriverObject, + OUT PDEVICE_OBJECT* KeyboardFdo); + +NTSTATUS +KeyboardInternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +/************************************ misc.c */ + +NTSTATUS +GreenDeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG CtlCode, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferSize, + IN OUT PVOID OutputBuffer OPTIONAL, + IN OUT PULONG OutputBufferSize); + +/************************************ pnp.c */ + +NTSTATUS STDCALL +GreenAddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT Pdo); + +/************************************ screen.c */ + +NTSTATUS +ScreenInitialize( + IN PDRIVER_OBJECT DriverObject, + OUT PDEVICE_OBJECT* ScreenFdo); + +NTSTATUS +ScreenWrite( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +ScreenDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); Property changes on: trunk/reactos/drivers/dd/green/green.h ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/green.rc --- trunk/reactos/drivers/dd/green/green.rc 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/green.rc 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "VT100 Server Driver\0" +#define REACTOS_STR_INTERNAL_NAME "green\0" +#define REACTOS_STR_ORIGINAL_FILENAME "green.sys\0" +#include <reactos/version.rc> Property changes on: trunk/reactos/drivers/dd/green/green.rc ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/keyboard.c --- trunk/reactos/drivers/dd/green/keyboard.c 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/keyboard.c 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,346 @@
+/* $Id: + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VT100 emulator + * FILE: drivers/dd/green/keyboard.c + * PURPOSE: Keyboard part of green management + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) + */ + +#define NDEBUG +#include "green.h" + +static BOOLEAN +TranslateCharToScanCodes( + IN PUCHAR InputBuffer, + IN ULONG InputBufferSize, + OUT KEYBOARD_INPUT_DATA* OutputBuffer, + OUT PULONG OutputBufferSize, + OUT PULONG BytesConsumed) +{ + BOOLEAN NormalKey = FALSE; + USHORT MakeCode; + + if (InputBufferSize == 0) + return FALSE; + + switch (*InputBuffer) + { + case 0x1b: MakeCode = 0x01; NormalKey = TRUE; break; /* ESC */ + + case '1': MakeCode = 0x02; NormalKey = TRUE; break; + case '2': MakeCode = 0x03; NormalKey = TRUE; break; + case '3': MakeCode = 0x04; NormalKey = TRUE; break; + case '4': MakeCode = 0x05; NormalKey = TRUE; break; + case '5': MakeCode = 0x06; NormalKey = TRUE; break; + case '6': MakeCode = 0x07; NormalKey = TRUE; break; + case '7': MakeCode = 0x08; NormalKey = TRUE; break; + case '8': MakeCode = 0x09; NormalKey = TRUE; break; + case '9': MakeCode = 0x0a; NormalKey = TRUE; break; + case '0': MakeCode = 0x0b; NormalKey = TRUE; break; + case '-': MakeCode = 0x0c; NormalKey = TRUE; break; + case '=': MakeCode = 0x0d; NormalKey = TRUE; break; + case '\b': MakeCode = 0x0e; NormalKey = TRUE; break; + + case '\t': MakeCode = 0x0f; NormalKey = TRUE; break; + case 'q': MakeCode = 0x10; NormalKey = TRUE; break; + case 'w': MakeCode = 0x11; NormalKey = TRUE; break; + case 'e': MakeCode = 0x12; NormalKey = TRUE; break; + case 'r': MakeCode = 0x13; NormalKey = TRUE; break; + case 't': MakeCode = 0x14; NormalKey = TRUE; break; + case 'y': MakeCode = 0x15; NormalKey = TRUE; break; + case 'u': MakeCode = 0x16; NormalKey = TRUE; break; + case 'i': MakeCode = 0x17; NormalKey = TRUE; break; + case 'o': MakeCode = 0x18; NormalKey = TRUE; break; + case 'p': MakeCode = 0x19; NormalKey = TRUE; break; + case '[': MakeCode = 0x1a; NormalKey = TRUE; break; + case ']': MakeCode = 0x1b; NormalKey = TRUE; break; + + case '\r': MakeCode = 0x1c; NormalKey = TRUE; break; + + case 'a': MakeCode = 0x1e; NormalKey = TRUE; break; + case 's': MakeCode = 0x1f; NormalKey = TRUE; break; + case 'd': MakeCode = 0x20; NormalKey = TRUE; break; + case 'f': MakeCode = 0x21; NormalKey = TRUE; break; + case 'g': MakeCode = 0x22; NormalKey = TRUE; break; + case 'h': MakeCode = 0x23; NormalKey = TRUE; break; + case 'j': MakeCode = 0x24; NormalKey = TRUE; break; + case 'k': MakeCode = 0x25; NormalKey = TRUE; break; + case 'l': MakeCode = 0x26; NormalKey = TRUE; break; + case ';': MakeCode = 0x27; NormalKey = TRUE; break; + case ''': MakeCode = 0x28; NormalKey = TRUE; break; + + case '`': MakeCode = 0x29; NormalKey = TRUE; break; + + case '\': MakeCode = 0x2b; NormalKey = TRUE; break; + + case 'z': MakeCode = 0x2c; NormalKey = TRUE; break; + case 'x': MakeCode = 0x2d; NormalKey = TRUE; break; + case 'c': MakeCode = 0x2e; NormalKey = TRUE; break; + case 'v': MakeCode = 0x2f; NormalKey = TRUE; break; + case 'b': MakeCode = 0x30; NormalKey = TRUE; break; + case 'n': MakeCode = 0x31; NormalKey = TRUE; break; + case 'm': MakeCode = 0x32; NormalKey = TRUE; break; + case ',': MakeCode = 0x33; NormalKey = TRUE; break; + case '.': MakeCode = 0x34; NormalKey = TRUE; break; + case '/': MakeCode = 0x35; NormalKey = TRUE; break; + + case ' ': MakeCode = 0x39; NormalKey = TRUE; break; + } + if (NormalKey && *OutputBufferSize >= 2) + { + OutputBuffer[0].MakeCode = MakeCode; + OutputBuffer[0].Flags = KEY_MAKE; + OutputBuffer[1].MakeCode = MakeCode; + OutputBuffer[1].Flags = KEY_BREAK; + *BytesConsumed = 2; + return TRUE; + } + + /* Consume strange character by ignoring it */ + DPRINT1("Green: strange byte received 0x%02x ('%c')\n", + *InputBuffer, *InputBuffer >= 32 ? *InputBuffer : '.'); + *BytesConsumed = 1; + return TRUE; +} + +NTSTATUS +KeyboardInitialize( + IN PDRIVER_OBJECT DriverObject, + OUT PDEVICE_OBJECT* KeyboardFdo) +{ + PDEVICE_OBJECT Fdo; + PKEYBOARD_DEVICE_EXTENSION DeviceExtension; + UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\Device\KeyboardClass1"); + NTSTATUS Status; + + DPRINT("Green: KeyboardInitialize() called\n"); + + Status = IoCreateDevice(DriverObject, + sizeof(KEYBOARD_DEVICE_EXTENSION), + &DeviceName, /* FIXME: don't hardcode string */ + FILE_DEVICE_KEYBOARD, + FILE_DEVICE_SECURE_OPEN, + TRUE, + &Fdo); + if (!NT_SUCCESS(Status)) + return Status; + + DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)Fdo->DeviceExtension; + RtlZeroMemory(DeviceExtension, sizeof(KEYBOARD_DEVICE_EXTENSION)); + DeviceExtension->Common.Type = Keyboard; + Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO; + Fdo->Flags &= ~DO_DEVICE_INITIALIZING; + + *KeyboardFdo = Fdo; + + return STATUS_SUCCESS; +} + +static VOID STDCALL +KeyboardDpcSendData( + IN PKDPC Dpc, + IN PVOID pDeviceExtension, /* real type PKEYBOARD_DEVICE_EXTENSION */ + IN PVOID Unused1, + IN PVOID Unused2) +{ + PKEYBOARD_DEVICE_EXTENSION DeviceExtension; + ULONG Queue; + ULONG InputDataConsumed; + + DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)pDeviceExtension; + + Queue = DeviceExtension->ActiveQueue % 2; + InterlockedIncrement((PLONG)&DeviceExtension->ActiveQueue); + (*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack) ( + DeviceExtension->ClassInformation.DeviceObject, + DeviceExtension->KeyboardInputData[Queue], + &DeviceExtension->KeyboardInputData[Queue][DeviceExtension->InputDataCou nt[Queue]], + &InputDataConsumed); + + DeviceExtension->InputDataCount[Queue] = 0; +} +static VOID STDCALL +KeyboardDeviceWorker( + PVOID Context) +{ + PDEVICE_OBJECT DeviceObject; + PKEYBOARD_DEVICE_EXTENSION DeviceExtension; + PGREEN_DEVICE_EXTENSION GreenDeviceExtension; + PDEVICE_OBJECT LowerDevice; + UCHAR Buffer[16]; /* Arbitrary size */ + ULONG BufferSize; + PIRP Irp; + IO_STATUS_BLOCK ioStatus; + KEVENT event; + KIRQL OldIrql; + ULONG i, Queue; + ULONG SpaceInQueue; + ULONG BytesConsumed; + PKEYBOARD_INPUT_DATA Input; + NTSTATUS Status; + + DPRINT("Green: KeyboardDeviceWorker() called\n"); + + DeviceObject = (PDEVICE_OBJECT)Context; + DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension; + LowerDevice = GreenDeviceExtension->Serial; + BufferSize = sizeof(Buffer); + + /* Initialize device extension */ + DeviceExtension->ActiveQueue = 0; + DeviceExtension->InputDataCount[0] = 0; + DeviceExtension->InputDataCount[1] = 0; + KeInitializeDpc(&DeviceExtension->KeyboardDpc, KeyboardDpcSendData, DeviceExtension); + RtlZeroMemory(&DeviceExtension->KeyboardInputData, sizeof(DeviceExtension->KeyboardInputData)); + + /* main read loop */ + while (TRUE) + { + KeInitializeEvent(&event, NotificationEvent, FALSE); + Irp = IoBuildSynchronousFsdRequest( + IRP_MJ_READ, + LowerDevice, + Buffer, BufferSize, + 0, + &event, + &ioStatus); + if (!Irp) + { + /* no memory actually, try later */ + CHECKPOINT; + KeStallExecutionProcessor(10); + continue; + } + + Status = IoCallDriver(LowerDevice, Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL); + Status = ioStatus.Status; + } + if (!NT_SUCCESS(Status)) + continue; + + /* Read all available data and process */ + i = 0; + while (i < ioStatus.Information) + { + Queue = DeviceExtension->ActiveQueue % 2; + + Input = &DeviceExtension->KeyboardInputData[Queue][DeviceExtension->InputDataCou nt[Queue]]; + + /* Translate current chars to scan codes */ + SpaceInQueue = KEYBOARD_BUFFER_SIZE - DeviceExtension->InputDataCount[Queue]; + if (TranslateCharToScanCodes( + &Buffer[i], /* input buffer */ + ioStatus.Information - i, /* input buffer size */ + Input, /* output buffer */ + &SpaceInQueue, /* output buffer size */ + &BytesConsumed)) /* bytes consumed in input buffer */ + { + DPRINT1("Green: got char 0x%02x (%c)\n", Buffer[i], Buffer[i] >= 32 ? Buffer[i] : ' '); + DeviceExtension->InputDataCount[Queue] += BytesConsumed; + + /* Send the data to the keyboard class driver */ + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + KeInsertQueueDpc(&DeviceExtension->KeyboardDpc, NULL, NULL); + KeLowerIrql(OldIrql); + i += BytesConsumed; + } + else + { + /* TranslateCharToScanCodes failed. Possible reasons: + * - not enough bytes in input buffer (escape control code; wait next received bytes) + * - not enough room in output buffer (wait for the Dpc to empty it) + * + * The best way to resolve this is to try later. + */ + i++; + } + } + } + + PsTerminateSystemThread(STATUS_SUCCESS); +} + +NTSTATUS +KeyboardInternalDeviceControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION Stack; + PKEYBOARD_DEVICE_EXTENSION DeviceExtension; + PGREEN_DEVICE_EXTENSION GreenDeviceExtension; + OBJECT_ATTRIBUTES objectAttributes; + PDEVICE_OBJECT LowerDevice; + NTSTATUS Status; + + Stack = IoGetCurrentIrpStackLocation(Irp); + Irp->IoStatus.Information = 0; + DeviceExtension = (PKEYBOARD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + GreenDeviceExtension = (PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension; + LowerDevice = GreenDeviceExtension->Serial; + DPRINT1("Green: LowerDevice %p\n", LowerDevice); + + switch (Stack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_INTERNAL_KEYBOARD_CONNECT: + { + ULONG Fcr; + + DPRINT("Green: IRP_MJ_INTERNAL_DEVICE_CONTROL / IOCTL_INTERNAL_KEYBOARD_CONNECT\n"); + if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(CONNECT_DATA)) + { + Status = STATUS_INVALID_PARAMETER; + break; + } + + DeviceExtension->ClassInformation = + *((PCLASS_INFORMATION)Stack->Parameters.DeviceIoControl.Type3InputBuffer ); + + /* Initialize serial port */ + Fcr = 0; + Status = GreenDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_FIFO_CONTROL, + &Fcr, sizeof(Fcr), NULL, NULL); + if (!NT_SUCCESS(Status)) break; + /* Set serial port speed */ + Status = GreenDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_BAUD_RATE, + &GreenDeviceExtension->BaudRate, sizeof(GreenDeviceExtension->BaudRate), NULL, NULL); + if (!NT_SUCCESS(Status)) break; + /* Set LCR */ + Status = GreenDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_LINE_CONTROL, + &GreenDeviceExtension->LineControl, sizeof(GreenDeviceExtension->LineControl), NULL, NULL); + if (!NT_SUCCESS(Status)) break; + + /* Set timeouts */ + Status = GreenDeviceIoControl(LowerDevice, IOCTL_SERIAL_SET_TIMEOUTS, + &GreenDeviceExtension->Timeouts, sizeof(GreenDeviceExtension->Timeouts), NULL, NULL); + if (!NT_SUCCESS(Status)) break; + + /* Start read loop */ + InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); + Status = PsCreateSystemThread( + &DeviceExtension->WorkerThreadHandle, + (ACCESS_MASK)0L, + &objectAttributes, + NULL, + NULL, + KeyboardDeviceWorker, + DeviceObject); + break; + } + default: + { + DPRINT("Green: IRP_MJ_INTERNAL_DEVICE_CONTROL / unknown ioctl code 0x%lx\n", + Stack->Parameters.DeviceIoControl.IoControlCode); + Status = STATUS_INVALID_DEVICE_REQUEST; + } + } + + Irp->IoStatus.Status = Status; + IoCompleteRequest (Irp, IO_NO_INCREMENT); + return Status; +} Property changes on: trunk/reactos/drivers/dd/green/keyboard.c ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/makefile --- trunk/reactos/drivers/dd/green/makefile 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/makefile 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,24 @@
+# $Id: + +PATH_TO_TOP = ../../.. + +TARGET_BOOTSTRAP = yes + +TARGET_TYPE = driver + +TARGET_NAME = green + +TARGET_CFLAGS = -Wall -Werror -D__USE_W32API + +TARGET_OBJECTS = \ + $(TARGET_NAME).o \ + createclose.o \ + dispatch.o \ + keyboard.o \ + misc.o \ + pnp.o \ + screen.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk Property changes on: trunk/reactos/drivers/dd/green/makefile ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/misc.c --- trunk/reactos/drivers/dd/green/misc.c 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/misc.c 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,60 @@
+/* $Id: + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VT100 emulator + * FILE: drivers/dd/green/misc.c + * PURPOSE: Misceallenous operations + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) + */ + +//#define NDEBUG +#include "green.h" + +NTSTATUS +GreenDeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN ULONG CtlCode, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferSize, + IN OUT PVOID OutputBuffer OPTIONAL, + IN OUT PULONG OutputBufferSize) +{ + KEVENT Event; + PIRP Irp; + IO_STATUS_BLOCK IoStatus; + NTSTATUS Status; + + KeInitializeEvent (&Event, NotificationEvent, FALSE); + + Irp = IoBuildDeviceIoControlRequest(CtlCode, + DeviceObject, + InputBuffer, + InputBufferSize, + OutputBuffer, + (OutputBufferSize) ? *OutputBufferSize : 0, + FALSE, + &Event, + &IoStatus); + if (Irp == NULL) + { + DPRINT("Green: IoBuildDeviceIoControlRequest() failed\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = IoCallDriver(DeviceObject, Irp); + + if (Status == STATUS_PENDING) + { + DPRINT("Green: Operation pending\n"); + KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL); + Status = IoStatus.Status; + } + + if (OutputBufferSize) + { + *OutputBufferSize = IoStatus.Information; + } + + return Status; +} Property changes on: trunk/reactos/drivers/dd/green/misc.c ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/pnp.c --- trunk/reactos/drivers/dd/green/pnp.c 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/pnp.c 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,87 @@
+/* $Id: + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VT100 emulator + * FILE: drivers/dd/green/pnp.c + * PURPOSE: IRP_MJ_PNP operations + * + * PROGRAMMERS: HervÚ Poussineau (hpoussin@reactos.com) + */ + +#define NDEBUG +#include "green.h" + +NTSTATUS STDCALL +GreenAddDevice( + IN PDRIVER_OBJECT DriverObject, + IN PDEVICE_OBJECT Pdo) +{ + PDEVICE_OBJECT Fdo = NULL; + PGREEN_DEVICE_EXTENSION DeviceExtension; + UNICODE_STRING serialPortName; + NTSTATUS Status; + + DPRINT("Green: AddDevice(DriverObject %p, Pdo %p)\n", DriverObject, Pdo); + + /* Create green FDO */ + Status = IoCreateDevice(DriverObject, + sizeof(GREEN_DEVICE_EXTENSION), + NULL, + FILE_DEVICE_UNKNOWN, + FILE_DEVICE_SECURE_OPEN, + TRUE, + &Fdo); + if (!NT_SUCCESS(Status)) + return Status; + + DeviceExtension = (PGREEN_DEVICE_EXTENSION)Fdo->DeviceExtension; + RtlZeroMemory(DeviceExtension, sizeof(GREEN_DEVICE_EXTENSION)); + DeviceExtension->Common.Type = Green; + + Status = KeyboardInitialize(DriverObject, &DeviceExtension->Keyboard); + if (!NT_SUCCESS(Status)) + { + IoDeleteDevice(Fdo); + return Status; + } + ((PKEYBOARD_DEVICE_EXTENSION)DeviceExtension->Keyboard->DeviceExtension) ->Green = Fdo; + + Status = ScreenInitialize(DriverObject, &DeviceExtension->Screen); + if (!NT_SUCCESS(Status)) + { + IoDeleteDevice(DeviceExtension->Keyboard); + IoDeleteDevice(Fdo); + return Status; + } + ((PSCREEN_DEVICE_EXTENSION)DeviceExtension->Screen->DeviceExtension)->Gr een = Fdo; + + /* initialize green Fdo */ + DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo); + DeviceExtension->LineControl.WordLength = 8; + DeviceExtension->LineControl.Parity = NO_PARITY; + DeviceExtension->LineControl.StopBits = STOP_BIT_1; + DeviceExtension->BaudRate = SERIAL_BAUD_38400; + DeviceExtension->Timeouts.ReadTotalTimeoutConstant = 1; /* not null */ + DeviceExtension->Timeouts.ReadIntervalTimeout = INFINITE; + DeviceExtension->Timeouts.ReadTotalTimeoutMultiplier = INFINITE; + DeviceExtension->Timeouts.WriteTotalTimeoutMultiplier = 0; /* FIXME */ + DeviceExtension->Timeouts.WriteTotalTimeoutConstant = 0; /* FIXME */ + + /* open associated serial port */ + RtlInitUnicodeString(&serialPortName, L"\Device\Serial1"); /* FIXME: don't hardcode string */ + Status = ObReferenceObjectByName( + &serialPortName, + OBJ_EXCLUSIVE | OBJ_KERNEL_HANDLE, + NULL, + (ACCESS_MASK)0, + IoDeviceObjectType, + KernelMode, + NULL, + (PVOID*)&DeviceExtension->Serial); + /* FIXME: we never ObDereferenceObject */ + + Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO; + Fdo->Flags &= ~DO_DEVICE_INITIALIZING; + + return Status; +} Property changes on: trunk/reactos/drivers/dd/green/pnp.c ___________________________________________________________________ Name: svn:keywords + author date id revision Name: svn:eol-style + native _____
Added: trunk/reactos/drivers/dd/green/screen.c --- trunk/reactos/drivers/dd/green/screen.c 2005-04-22 15:26:14 UTC (rev 14748) +++ trunk/reactos/drivers/dd/green/screen.c 2005-04-22 19:57:03 UTC (rev 14749) @@ -0,0 +1,544 @@
+/* $Id: + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS VT100 emulator + * FILE: drivers/dd/green/screen.c + * PURPOSE: Screen part of green management + * + * PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de) + * Art Yerkes + * HervÚ Poussineau (hpoussin@reactos.com) + */ + +#define NDEBUG +#include "green.h" +#include <stdarg.h> + +#define ESC ((UCHAR)0x1b) + +/* Force a move of the cursor on each printer char. + * Very useful for debug, but it is very slow... + */ +//#define FORCE_POSITION + +/* UCHAR is promoted to int when passed through '...', + * so we get int with va_arg and cast them back to UCHAR. + */ +static VOID +AddToSendBuffer( + IN PSCREEN_DEVICE_EXTENSION DeviceExtension, + IN ULONG NumberOfChars, + ... /* IN int */) +{ + PIRP Irp; + IO_STATUS_BLOCK ioStatus; + va_list args; + PDEVICE_OBJECT SerialDevice; + ULONG SizeLeft; + int CurrentInt; + UCHAR CurrentChar; + NTSTATUS Status; + + SizeLeft = sizeof(DeviceExtension->SendBuffer) - DeviceExtension->SendBufferPosition; + if (SizeLeft < NumberOfChars * 2 || NumberOfChars == 0) + { + SerialDevice = ((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Seri al; + Irp = IoBuildSynchronousFsdRequest( + IRP_MJ_WRITE, + SerialDevice, [truncated at 1000 lines; 502 more skipped]