Some upgrades for green:
- Either create the blue device or attach to it
- If we can't open a serial device, forward the IRP to the original blue
- Scrolling fix
- Don't do DO_BUFFERED_IO if we use Irp->UserBuffer
- Pass a zero offset when writing to serial port
Green now displays correctly and fails back correctly. Keyboard part
doesn't
yet coexist with current ReactOS. That's next.
Modified: trunk/reactos/drivers/dd/green/green.h
Modified: trunk/reactos/drivers/dd/green/pnp.c
Modified: trunk/reactos/drivers/dd/green/screen.c
_____
Modified: trunk/reactos/drivers/dd/green/green.h
--- trunk/reactos/drivers/dd/green/green.h 2005-10-30 22:19:33 UTC
(rev 18897)
+++ trunk/reactos/drivers/dd/green/green.h 2005-10-30 22:33:26 UTC
(rev 18898)
@@ -76,6 +76,7 @@
UCHAR SendBuffer[1024];
ULONG SendBufferPosition;
+ PDEVICE_OBJECT PreviousBlue;
} SCREEN_DEVICE_EXTENSION, *PSCREEN_DEVICE_EXTENSION;
typedef struct _GREEN_DEVICE_EXTENSION
_____
Modified: trunk/reactos/drivers/dd/green/pnp.c
--- trunk/reactos/drivers/dd/green/pnp.c 2005-10-30 22:19:33 UTC
(rev 18897)
+++ trunk/reactos/drivers/dd/green/pnp.c 2005-10-30 22:33:26 UTC
(rev 18898)
@@ -32,8 +32,12 @@
FILE_DEVICE_SECURE_OPEN,
TRUE,
&Fdo);
+
if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Status = %08x\n", Status);
return Status;
+ }
DeviceExtension = (PGREEN_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(GREEN_DEVICE_EXTENSION));
@@ -43,6 +47,7 @@
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(Fdo);
+ DPRINT1("Status = %08x\n", Status);
return Status;
}
((PKEYBOARD_DEVICE_EXTENSION)DeviceExtension->Keyboard->DeviceExtension)
->Green = Fdo;
@@ -52,6 +57,7 @@
{
IoDeleteDevice(DeviceExtension->Keyboard);
IoDeleteDevice(Fdo);
+ DPRINT1("Status = %08x\n", Status);
return Status;
}
((PSCREEN_DEVICE_EXTENSION)DeviceExtension->Screen->DeviceExtension)->Gr
een = Fdo;
@@ -84,5 +90,6 @@
Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+ DPRINT1("Status = %08x\n", Status);
return Status;
}
_____
Modified: trunk/reactos/drivers/dd/green/screen.c
--- trunk/reactos/drivers/dd/green/screen.c 2005-10-30 22:19:33 UTC
(rev 18897)
+++ trunk/reactos/drivers/dd/green/screen.c 2005-10-30 22:33:26 UTC
(rev 18898)
@@ -38,7 +38,10 @@
int CurrentInt;
UCHAR CurrentChar;
NTSTATUS Status;
+ LARGE_INTEGER ZeroOffset;
+ ZeroOffset.QuadPart = 0;
+
SizeLeft = sizeof(DeviceExtension->SendBuffer) -
DeviceExtension->SendBufferPosition;
if (SizeLeft < NumberOfChars * 2 || NumberOfChars == 0)
{
@@ -47,7 +50,7 @@
IRP_MJ_WRITE,
SerialDevice,
DeviceExtension->SendBuffer,
DeviceExtension->SendBufferPosition,
- NULL, /* StartingOffset */
+ &ZeroOffset,
NULL, /* Event */
&ioStatus);
if (!Irp)
@@ -55,7 +58,9 @@
DPRINT1("Green: IoBuildSynchronousFsdRequest()
failed. Unable to flush output buffer\n");
return;
}
+
Status = IoCallDriver(SerialDevice, Irp);
+
if (!NT_SUCCESS(Status) && Status != STATUS_PENDING)
{
DPRINT1("Green: IoCallDriver() failed. Status =
0x%08lx\n", Status);
@@ -69,6 +74,7 @@
while (NumberOfChars-- > 0)
{
CurrentInt = va_arg(args, int);
+
if (CurrentInt > 0)
{
CurrentChar = (UCHAR)CurrentInt;
@@ -107,7 +113,7 @@
IN PDRIVER_OBJECT DriverObject,
OUT PDEVICE_OBJECT* ScreenFdo)
{
- PDEVICE_OBJECT Fdo;
+ PDEVICE_OBJECT Fdo, PreviousBlue = NULL;
PSCREEN_DEVICE_EXTENSION DeviceExtension;
UNICODE_STRING DeviceName =
RTL_CONSTANT_STRING(L"\\Device\\BlueScreen");
NTSTATUS Status;
@@ -121,12 +127,56 @@
FILE_DEVICE_SECURE_OPEN,
TRUE,
&Fdo);
- if (!NT_SUCCESS(Status))
+
+ if (Status == STATUS_OBJECT_NAME_COLLISION)
+ {
+ DPRINT("Green: Attaching to old blue\n");
+
+ /* Suggested by hpoussin .. Hide previous blue device
+ * This makes us able to coexist with blue, and install
+ * when loaded */
+ Status = IoCreateDevice(DriverObject,
+ sizeof(SCREEN_DEVICE_EXTENSION),
+ NULL,
+ FILE_DEVICE_SCREEN,
+ FILE_DEVICE_SECURE_OPEN,
+ TRUE,
+ &Fdo);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Status = IoAttachDevice(
+ Fdo,
+ &DeviceName, /* FIXME: don't hardcode string */
+ &PreviousBlue);
+
+ if (!NT_SUCCESS(Status)) {
+ IoDeleteDevice(Fdo);
+ return Status;
+ }
+ }
+ else if (!NT_SUCCESS(Status))
return Status;
+ /* We definately have a device object. PreviousBlue may or may
+ * not be null */
+
DeviceExtension =
(PSCREEN_DEVICE_EXTENSION)Fdo->DeviceExtension;
RtlZeroMemory(DeviceExtension, sizeof(SCREEN_DEVICE_EXTENSION));
DeviceExtension->Common.Type = Screen;
+ DeviceExtension->PreviousBlue = PreviousBlue;
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* If a device was attached, detach it first */
+ if (DeviceExtension->PreviousBlue)
+ IoDetachDevice(DeviceExtension->PreviousBlue);
+
+ IoDeleteDevice(Fdo);
+ return Status;
+ }
+
/* initialize screen */
DeviceExtension->Columns = 80;
DeviceExtension->Rows = 25;
@@ -136,6 +186,10 @@
2 * DeviceExtension->Columns * DeviceExtension->Rows *
sizeof(UCHAR));
if (!DeviceExtension->VideoMemory)
{
+ /* If a device was attached, detach it first */
+ if (DeviceExtension->PreviousBlue)
+ IoDetachDevice(DeviceExtension->PreviousBlue);
+
IoDeleteDevice(Fdo);
return STATUS_INSUFFICIENT_RESOURCES;
}
@@ -150,7 +204,7 @@
AddToSendBuffer(DeviceExtension, 4, ESC, '[', '7', 'l'); /*
disable line wrap */
AddToSendBuffer(DeviceExtension, 4, ESC, '[', '3', 'g'); /*
clear all tabs */
- Fdo->Flags |= DO_POWER_PAGABLE | DO_BUFFERED_IO;
+ Fdo->Flags |= DO_POWER_PAGABLE;
Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
*ScreenFdo = Fdo;
@@ -166,6 +220,7 @@
PIO_STACK_LOCATION Stack;
PUCHAR Buffer;
PSCREEN_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_OBJECT SerialDevice;
PUCHAR VideoMemory; /* FIXME: is it useful? */
ULONG VideoMemorySize; /* FIXME: is it useful? */
@@ -181,16 +236,27 @@
DeviceExtension =
(PSCREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
VideoMemory = DeviceExtension->VideoMemory;
+ SerialDevice =
((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Seri
al;
+ if (!SerialDevice)
+ {
+ DPRINT1("Calling blue\n");
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(DeviceExtension->PreviousBlue, Irp);
+ }
+
Columns = DeviceExtension->Columns;
Rows = DeviceExtension->Rows;
CursorX = (DeviceExtension->LogicalOffset / 2) % Columns + 1;
CursorY = (DeviceExtension->LogicalOffset / 2) / Columns + 1;
VideoMemorySize = Columns * Rows * 2 * sizeof(UCHAR);
- DPRINT1("Y: %lu\n", CursorY);
- DPRINT1("Buffer =");
+
+#if DBG
+ DPRINT("Y: %lu\n", CursorY);
+ DPRINT("Buffer =");
for (i = 0; i < Stack->Parameters.Write.Length; i++)
DbgPrint(" 0x%02x", Buffer[i]);
DbgPrint("\n");
+#endif
if (!(DeviceExtension->Mode & ENABLE_PROCESSED_OUTPUT))
{
@@ -228,6 +294,7 @@
{
CursorY++;
CursorX = 1;
+ AddToSendBuffer(DeviceExtension,
1, '\n');
AddToSendBuffer(DeviceExtension,
6, ESC, '[', -(int)CursorY, ';', '1', 'H');
break;
}
@@ -268,17 +335,18 @@
if (CursorX > Columns)
{
CursorX = 1;
- DPRINT1("Y: %lu ->
%lu\n", CursorY, CursorY + 1);
+ DPRINT("Y: %lu ->
%lu\n", CursorY, CursorY + 1);
CursorY++;
AddToSendBuffer(DeviceExtension, 6, ESC, '[', -(int)CursorY, ';',
'1',
'H');
}
}
}
- if (CursorY > Rows)
+ if (CursorY >= Rows)
{
- DPRINT1("Y: %lu -> %lu\n", CursorY,
CursorY - 1);
+ DPRINT("Y: %lu -> %lu\n", CursorY,
CursorY - 1);
CursorY--;
+ AddToSendBuffer(DeviceExtension, 6, ESC,
'[', -(int)1, ';', -(int)(Rows), 'r');
AddToSendBuffer(DeviceExtension, 2, ESC,
'D');
AddToSendBuffer(DeviceExtension, 6, ESC,
'[', -(int)CursorY, ';', -(int)CursorX, 'H');
}
@@ -304,11 +372,20 @@
{
PIO_STACK_LOCATION Stack;
PSCREEN_DEVICE_EXTENSION DeviceExtension;
+ PDEVICE_OBJECT SerialDevice;
NTSTATUS Status;
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceExtension =
(PSCREEN_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ SerialDevice =
((PGREEN_DEVICE_EXTENSION)DeviceExtension->Green->DeviceExtension)->Seri
al;
+ if (!SerialDevice)
+ {
+ DPRINT1("Calling blue\n");
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(DeviceExtension->PreviousBlue, Irp);
+ }
+
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO:
@@ -510,7 +587,7 @@
-(int)(ConsoleDraw->Y +
y), ';',
-(int)(ConsoleDraw->X),
'H');
Video = (PUCHAR)(ConsoleDraw +
1);
- Video = &Video[((ConsoleDraw->Y
+ y) * DeviceExtension->Columns + ConsoleDraw->X) * 2];
+ Video = &Video[((ConsoleDraw->Y
+ y) * /*DeviceExtension->Columns +*/ ConsoleDraw->X) * 2];
for (x = 0; x <
ConsoleDraw->SizeX; x++)
{
AddToSendBuffer(DeviceExtension, 1, Video[x * 2]);