2 * PROJECT: ReactOS VT100 emulator
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/base/green/screen.c
5 * PURPOSE: IRP_MJ_PNP operations
6 * PROGRAMMERS: Copyright 2005 Eric Kohl (ekohl@abo.rhein-zeitung.de)
7 * Copyright 2005 Art Yerkes
8 * Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
16 #define ESC ((UCHAR)0x1b)
18 /* Force a move of the cursor on each printer char.
19 * Very useful for debug, but it is very slow...
21 //#define FORCE_POSITION
23 /* UCHAR is promoted to int when passed through '...',
24 * so we get int with va_arg and cast them back to UCHAR.
28 IN PSCREEN_DEVICE_EXTENSION DeviceExtension
,
29 IN ULONG NumberOfChars
,
33 IO_STATUS_BLOCK ioStatus
;
35 PDEVICE_OBJECT SerialDevice
;
40 LARGE_INTEGER ZeroOffset
;
42 ZeroOffset
.QuadPart
= 0;
44 SizeLeft
= sizeof(DeviceExtension
->SendBuffer
) - DeviceExtension
->SendBufferPosition
;
45 if (SizeLeft
< NumberOfChars
* 2 || NumberOfChars
== 0)
47 SerialDevice
= ((PGREEN_DEVICE_EXTENSION
)DeviceExtension
->Green
->DeviceExtension
)->Serial
;
48 Irp
= IoBuildSynchronousFsdRequest(
51 DeviceExtension
->SendBuffer
, DeviceExtension
->SendBufferPosition
,
57 DPRINT1("IoBuildSynchronousFsdRequest() failed. Unable to flush output buffer\n");
61 Status
= IoCallDriver(SerialDevice
, Irp
);
63 if (!NT_SUCCESS(Status
) && Status
!= STATUS_PENDING
)
65 DPRINT1("IoCallDriver() failed. Status = 0x%08lx\n", Status
);
68 DeviceExtension
->SendBufferPosition
= 0;
69 SizeLeft
= sizeof(DeviceExtension
->SendBuffer
);
72 va_start(args
, NumberOfChars
);
73 while (NumberOfChars
-- > 0)
75 CurrentInt
= va_arg(args
, int);
79 CurrentChar
= (UCHAR
)CurrentInt
;
81 /* Why 0xff chars are printed on a 'dir' ? */
82 if (CurrentChar
== 0xff) CurrentChar
= ' ';
84 DeviceExtension
->SendBuffer
[DeviceExtension
->SendBufferPosition
++] = CurrentChar
;
87 else if (CurrentInt
== 0)
89 DeviceExtension
->SendBuffer
[DeviceExtension
->SendBufferPosition
++] = '0';
94 CurrentInt
= -CurrentInt
;
95 ASSERT(CurrentInt
< 100);
98 DeviceExtension
->SendBuffer
[DeviceExtension
->SendBufferPosition
++] =
99 (CurrentInt
/ 10) % 10 + '0';
102 DeviceExtension
->SendBuffer
[DeviceExtension
->SendBufferPosition
++] =
103 CurrentInt
% 10 + '0';
112 IN PDRIVER_OBJECT DriverObject
,
113 IN PDEVICE_OBJECT Pdo
)
115 /* We want to be an upper filter of Blue, if it is existing.
116 * We also *have to* create a Fdo on top of the given Pdo.
117 * Hence, we have 2 cases:
118 * - Blue doesn't exist -> Create a unique Fdo (named Blue) at
119 * the top of the given Pdo
120 * - Blue does exist -> Create a Fdo at the top of the existing
121 * DO, and create a "pass to Green" FDO at the top of the Pdo
123 PDEVICE_OBJECT Fdo
= NULL
;
124 PDEVICE_OBJECT PassThroughFdo
= NULL
;
125 PDEVICE_OBJECT LowerDevice
= NULL
;
126 PDEVICE_OBJECT PreviousBlue
= NULL
;
127 PSCREEN_DEVICE_EXTENSION DeviceExtension
= NULL
;
128 UNICODE_STRING BlueScreenName
= RTL_CONSTANT_STRING(L
"\\Device\\BlueScreen");
131 DPRINT("ScreenInitialize() called\n");
133 /* Try to create a unique Fdo */
134 Status
= IoCreateDevice(
136 sizeof(SCREEN_DEVICE_EXTENSION
),
139 FILE_DEVICE_SECURE_OPEN
,
143 if (Status
== STATUS_OBJECT_NAME_COLLISION
)
145 DPRINT("Attaching to old blue\n");
147 /* Suggested by hpoussin .. Hide previous blue device
148 * This makes us able to coexist with blue, and install
150 Status
= IoCreateDevice(
152 sizeof(SCREEN_DEVICE_EXTENSION
),
155 FILE_DEVICE_SECURE_OPEN
,
158 if (!NT_SUCCESS(Status
))
160 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status
);
164 /* Initialize some fields, as IoAttachDevice will trigger the
165 * sending of IRP_MJ_CLEANUP/IRP_MJ_CLOSE. We have to know where to
166 * dispatch these IRPs... */
167 ((PSCREEN_DEVICE_EXTENSION
)Fdo
->DeviceExtension
)->Common
.Type
= ScreenPDO
;
168 Status
= IoAttachDevice(
172 if (!NT_SUCCESS(Status
))
174 DPRINT("IoAttachDevice() failed with status 0x%08lx\n", Status
);
177 PreviousBlue
= LowerDevice
;
179 /* Attach a faked FDO to PDO */
180 Status
= IoCreateDevice(
182 sizeof(COMMON_FDO_DEVICE_EXTENSION
),
185 FILE_DEVICE_SECURE_OPEN
,
188 if (!NT_SUCCESS(Status
))
190 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status
);
193 ((PCOMMON_FDO_DEVICE_EXTENSION
)PassThroughFdo
->DeviceExtension
)->Type
= PassThroughFDO
;
194 ((PCOMMON_FDO_DEVICE_EXTENSION
)PassThroughFdo
->DeviceExtension
)->LowerDevice
= Fdo
;
195 PassThroughFdo
->StackSize
= Fdo
->StackSize
+ 1;
197 else if (NT_SUCCESS(Status
))
199 /* Attach the named Fdo on top of Pdo */
200 LowerDevice
= IoAttachDeviceToDeviceStack(Fdo
, Pdo
);
204 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", Status
);
208 /* We definately have a device object. PreviousBlue may or may
210 DeviceExtension
= (PSCREEN_DEVICE_EXTENSION
)Fdo
->DeviceExtension
;
211 RtlZeroMemory(DeviceExtension
, sizeof(SCREEN_DEVICE_EXTENSION
));
212 DeviceExtension
->Common
.Type
= ScreenFDO
;
213 DeviceExtension
->Common
.LowerDevice
= LowerDevice
;
214 DeviceExtension
->Green
= ((PGREEN_DRIVER_EXTENSION
)IoGetDriverObjectExtension(DriverObject
, DriverObject
))->GreenMainDO
;
215 ((PGREEN_DEVICE_EXTENSION
)DeviceExtension
->Green
->DeviceExtension
)->ScreenFdo
= Fdo
;
216 DeviceExtension
->PreviousBlue
= PreviousBlue
;
217 IoAttachDeviceToDeviceStack(PassThroughFdo
? PassThroughFdo
: Fdo
, Pdo
);
219 /* initialize screen */
220 DeviceExtension
->Columns
= 80;
221 DeviceExtension
->Rows
= 25;
222 DeviceExtension
->ScanLines
= 16;
223 DeviceExtension
->VideoMemory
= (PUCHAR
)ExAllocatePool(
225 2 * DeviceExtension
->Columns
* DeviceExtension
->Rows
* sizeof(UCHAR
));
226 if (!DeviceExtension
->VideoMemory
)
228 DPRINT("ExAllocatePool() failed\n");
229 Status
= STATUS_INSUFFICIENT_RESOURCES
;
232 DeviceExtension
->TabWidth
= 8;
234 /* more initialization */
235 DeviceExtension
->Mode
= ENABLE_PROCESSED_OUTPUT
|
236 ENABLE_WRAP_AT_EOL_OUTPUT
;
238 /* initialize screen at next write */
239 AddToSendBuffer(DeviceExtension
, 2, ESC
, 'c'); /* reset device */
240 AddToSendBuffer(DeviceExtension
, 4, ESC
, '[', '7', 'l'); /* disable line wrap */
241 AddToSendBuffer(DeviceExtension
, 4, ESC
, '[', '3', 'g'); /* clear all tabs */
243 Fdo
->Flags
|= DO_POWER_PAGABLE
;
244 Fdo
->Flags
&= ~DO_DEVICE_INITIALIZING
;
246 Status
= STATUS_SUCCESS
;
249 if (!NT_SUCCESS(Status
))
252 ExFreePool(DeviceExtension
->VideoMemory
);
254 IoDetachDevice(LowerDevice
);
258 IoDeleteDevice(PassThroughFdo
);
266 IN PDEVICE_OBJECT DeviceObject
,
269 PIO_STACK_LOCATION Stack
;
271 PSCREEN_DEVICE_EXTENSION DeviceExtension
;
272 PDEVICE_OBJECT SerialDevice
;
273 PUCHAR VideoMemory
; /* FIXME: is it useful? */
274 ULONG VideoMemorySize
; /* FIXME: is it useful? */
277 ULONG CursorX
, CursorY
;
280 DPRINT("ScreenWrite() called\n");
282 Stack
= IoGetCurrentIrpStackLocation (Irp
);
283 Buffer
= Irp
->UserBuffer
;
284 DeviceExtension
= (PSCREEN_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
285 VideoMemory
= DeviceExtension
->VideoMemory
;
287 SerialDevice
= ((PGREEN_DEVICE_EXTENSION
)DeviceExtension
->Green
->DeviceExtension
)->Serial
;
290 DPRINT1("Calling blue\n");
291 IoSkipCurrentIrpStackLocation(Irp
);
292 return IoCallDriver(DeviceExtension
->PreviousBlue
, Irp
);
295 Columns
= DeviceExtension
->Columns
;
296 Rows
= DeviceExtension
->Rows
;
297 CursorX
= (DeviceExtension
->LogicalOffset
/ 2) % Columns
+ 1;
298 CursorY
= (DeviceExtension
->LogicalOffset
/ 2) / Columns
+ 1;
299 VideoMemorySize
= Columns
* Rows
* 2 * sizeof(UCHAR
);
301 if (!(DeviceExtension
->Mode
& ENABLE_PROCESSED_OUTPUT
))
303 /* raw output mode */
305 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
306 IoCompleteRequest (Irp
, IO_NO_INCREMENT
);
308 return STATUS_NOT_SUPPORTED
;
312 for (i
= 0; i
< Stack
->Parameters
.Write
.Length
; i
++, Buffer
++)
321 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)CursorY
, ';', -(int)CursorX
, 'H');
322 AddToSendBuffer(DeviceExtension
, 1, ' ');
323 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)CursorY
, ';', -(int)CursorX
, 'H');
325 else if (CursorY
> 1)
329 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)CursorY
, ';', -(int)CursorX
, 'H');
337 AddToSendBuffer(DeviceExtension
, 1, '\n');
338 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)CursorY
, ';', '1', 'H');
345 AddToSendBuffer(DeviceExtension
, 4, ESC
, '[', -(int)(CursorX
-1), 'D');
352 ULONG Offset
= DeviceExtension
->TabWidth
- (CursorX
% DeviceExtension
->TabWidth
);
353 for (j
= 0; j
< Offset
; j
++)
355 #ifdef FORCE_POSITION
356 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)CursorY
, ';', -(int)CursorX
, 'H');
358 AddToSendBuffer(DeviceExtension
, 1, ' ');
360 if (CursorX
> Columns
)
370 #ifdef FORCE_POSITION
371 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)CursorY
, ';', -(int)CursorX
, 'H');
373 AddToSendBuffer(DeviceExtension
, 1, *Buffer
);
375 if (CursorX
> Columns
)
378 DPRINT("Y: %lu -> %lu\n", CursorY
, CursorY
+ 1);
380 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)CursorY
, ';', '1', 'H');
387 DPRINT("Y: %lu -> %lu\n", CursorY
, CursorY
- 1);
389 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)1, ';', -(int)(Rows
), 'r');
390 AddToSendBuffer(DeviceExtension
, 2, ESC
, 'D');
391 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[', -(int)CursorY
, ';', -(int)CursorX
, 'H');
396 DeviceExtension
->LogicalOffset
= ((CursorX
-1) + (CursorY
-1) * Columns
) * 2;
398 /* flush output buffer */
399 AddToSendBuffer(DeviceExtension
, 0);
401 /* Call lower driver */
402 IoSkipCurrentIrpStackLocation(Irp
);
403 return IoCallDriver(DeviceExtension
->Common
.LowerDevice
, Irp
);
408 IN PDEVICE_OBJECT DeviceObject
,
411 PIO_STACK_LOCATION Stack
;
412 PSCREEN_DEVICE_EXTENSION DeviceExtension
;
413 PDEVICE_OBJECT SerialDevice
;
416 Stack
= IoGetCurrentIrpStackLocation(Irp
);
417 DeviceExtension
= (PSCREEN_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
418 SerialDevice
= ((PGREEN_DEVICE_EXTENSION
)DeviceExtension
->Green
->DeviceExtension
)->Serial
;
421 DPRINT1("Calling blue\n");
422 IoSkipCurrentIrpStackLocation(Irp
);
423 return IoCallDriver(DeviceExtension
->PreviousBlue
, Irp
);
426 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
429 case IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO
:
431 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
;
432 DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_SCREEN_BUFFER_INFO\n");
434 pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
436 pcsbi
->dwSize
.X
= DeviceExtension
->Columns
;
437 pcsbi
->dwSize
.Y
= DeviceExtension
->Rows
;
439 pcsbi
->dwCursorPosition
.X
= (SHORT
)(DeviceExtension
->LogicalOffset
% DeviceExtension
->Columns
);
440 pcsbi
->dwCursorPosition
.Y
= (SHORT
)(DeviceExtension
->LogicalOffset
/ DeviceExtension
->Columns
);
442 pcsbi
->wAttributes
= DeviceExtension
->CharAttribute
;
444 pcsbi
->srWindow
.Left
= 1;
445 pcsbi
->srWindow
.Right
= DeviceExtension
->Columns
;
446 pcsbi
->srWindow
.Top
= 1;
447 pcsbi
->srWindow
.Bottom
= DeviceExtension
->Rows
;
449 pcsbi
->dwMaximumWindowSize
.X
= DeviceExtension
->Columns
;
450 pcsbi
->dwMaximumWindowSize
.Y
= DeviceExtension
->Rows
;
452 Irp
->IoStatus
.Information
= sizeof(CONSOLE_SCREEN_BUFFER_INFO
);
453 Status
= STATUS_SUCCESS
;
456 case IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO
:
458 PCONSOLE_SCREEN_BUFFER_INFO pcsbi
;
459 DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_SCREEN_BUFFER_INFO\n");
461 pcsbi
= (PCONSOLE_SCREEN_BUFFER_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
462 /* FIXME: remove */ { pcsbi
->dwCursorPosition
.X
++; }
463 /* FIXME: remove */ { pcsbi
->dwCursorPosition
.Y
++; }
464 ASSERT(pcsbi
->dwCursorPosition
.X
>= 1);
465 ASSERT(pcsbi
->dwCursorPosition
.Y
>= 1);
466 ASSERT(pcsbi
->dwCursorPosition
.X
<= DeviceExtension
->Columns
);
467 ASSERT(pcsbi
->dwCursorPosition
.Y
<= DeviceExtension
->Rows
);
469 DeviceExtension
->LogicalOffset
= (
470 (pcsbi
->dwCursorPosition
.Y
-1) * DeviceExtension
->Columns
+
471 (pcsbi
->dwCursorPosition
.X
-1)) * 2;
472 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[',
473 -(int)pcsbi
->dwCursorPosition
.Y
, ';',
474 -(int)pcsbi
->dwCursorPosition
.X
, 'H');
477 AddToSendBuffer(DeviceExtension
, 0);
479 DeviceExtension
->CharAttribute
= pcsbi
->wAttributes
;
481 Irp
->IoStatus
.Information
= 0;
482 Status
= STATUS_SUCCESS
;
485 case IOCTL_CONSOLE_GET_CURSOR_INFO
:
487 PCONSOLE_CURSOR_INFO pcci
= (PCONSOLE_CURSOR_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
488 DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_CURSOR_INFO\n");
491 pcci
->bVisible
= TRUE
;
493 Irp
->IoStatus
.Information
= sizeof (CONSOLE_CURSOR_INFO
);
494 Status
= STATUS_SUCCESS
;
497 case IOCTL_CONSOLE_GET_MODE
:
499 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
500 DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_GET_MODE\n");
502 pcm
->dwMode
= DeviceExtension
->Mode
;
504 Irp
->IoStatus
.Information
= sizeof(CONSOLE_MODE
);
505 Status
= STATUS_SUCCESS
;
508 case IOCTL_CONSOLE_SET_MODE
:
510 PCONSOLE_MODE pcm
= (PCONSOLE_MODE
)Irp
->AssociatedIrp
.SystemBuffer
;
511 DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_MODE\n");
513 DeviceExtension
->Mode
= pcm
->dwMode
;
515 Irp
->IoStatus
.Information
= 0;
516 Status
= STATUS_SUCCESS
;
519 case IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE
:
521 DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE\n");
522 Status
= STATUS_NOT_IMPLEMENTED
; /* FIXME: IOCTL_CONSOLE_FILL_OUTPUT_ATTRIBUTE */
525 case IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE
:
527 DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE\n");
528 Status
= STATUS_NOT_IMPLEMENTED
; /* FIXME: IOCTL_CONSOLE_READ_OUTPUT_ATTRIBUTE */
531 case IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE
:
533 DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE\n");
534 Status
= STATUS_NOT_IMPLEMENTED
; /* FIXME: IOCTL_CONSOLE_WRITE_OUTPUT_ATTRIBUTE */
537 case IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE
:
539 DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_SET_TEXT_ATTRIBUTE\n");
541 DeviceExtension
->CharAttribute
= (WORD
)*(PWORD
)Irp
->AssociatedIrp
.SystemBuffer
;
542 Irp
->IoStatus
.Information
= 0;
543 Status
= STATUS_SUCCESS
;
546 case IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER
:
548 DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER\n");
549 Status
= STATUS_NOT_IMPLEMENTED
; /* FIXME:IOCTL_CONSOLE_FILL_OUTPUT_CHARACTER */
552 case IOCTL_CONSOLE_READ_OUTPUT_CHARACTER
:
554 DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_READ_OUTPUT_CHARACTER\n");
555 Status
= STATUS_NOT_IMPLEMENTED
; /* FIXME: IOCTL_CONSOLE_READ_OUTPUT_CHARACTER */
558 case IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER
:
560 DPRINT1("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER\n");
561 Status
= STATUS_NOT_IMPLEMENTED
; /* FIXME: IOCTL_CONSOLE_WRITE_OUTPUT_CHARACTER */
564 case IOCTL_CONSOLE_DRAW
:
566 PCONSOLE_DRAW ConsoleDraw
;
569 BOOLEAN DoOptimization
= FALSE
;
570 DPRINT("IRP_MJ_DEVICE_CONTROL / IOCTL_CONSOLE_DRAW\n");
572 ConsoleDraw
= (PCONSOLE_DRAW
)MmGetSystemAddressForMdl(Irp
->MdlAddress
);
573 /* FIXME: remove */ { ConsoleDraw
->X
++; ConsoleDraw
->CursorX
++; }
574 /* FIXME: remove */ { ConsoleDraw
->Y
++; ConsoleDraw
->CursorY
++; }
575 DPRINT1("%lu %lu %lu %lu\n",
576 ConsoleDraw
->X
, ConsoleDraw
->Y
,
577 ConsoleDraw
->SizeX
, ConsoleDraw
->SizeY
);
578 ASSERT(ConsoleDraw
->X
>= 1);
579 ASSERT(ConsoleDraw
->Y
>= 1);
580 ASSERT(ConsoleDraw
->X
<= DeviceExtension
->Columns
);
581 ASSERT(ConsoleDraw
->Y
<= DeviceExtension
->Rows
);
582 ASSERT(ConsoleDraw
->X
+ ConsoleDraw
->SizeX
>= 1);
583 ASSERT(ConsoleDraw
->Y
+ ConsoleDraw
->SizeY
>= 1);
584 ASSERT(ConsoleDraw
->X
+ ConsoleDraw
->SizeX
- 1 <= DeviceExtension
->Columns
);
585 ASSERT(ConsoleDraw
->Y
+ ConsoleDraw
->SizeY
- 1 <= DeviceExtension
->Rows
);
586 ASSERT(ConsoleDraw
->CursorX
>= 1);
587 ASSERT(ConsoleDraw
->CursorY
>= 1);
588 ASSERT(ConsoleDraw
->CursorX
<= DeviceExtension
->Columns
);
589 ASSERT(ConsoleDraw
->CursorY
<= DeviceExtension
->Rows
);
592 if (ConsoleDraw
->X
== 1
593 && ConsoleDraw
->Y
== 1
594 && ConsoleDraw
->SizeX
== DeviceExtension
->Columns
595 && ConsoleDraw
->SizeY
== DeviceExtension
->Rows
)
598 /* search if we need to clear all screen */
599 DoOptimization
= TRUE
;
600 Video
= (PUCHAR
)(ConsoleDraw
+ 1);
602 while (DoOptimization
&& x
< DeviceExtension
->Columns
* DeviceExtension
->Rows
)
604 if (Video
[x
++] != ' ')
607 DoOptimization
= FALSE
;
609 /*if (Video[x++] != DeviceExtension->CharAttribute) DoOptimization = FALSE; */
614 AddToSendBuffer(DeviceExtension
, 4, ESC
, '[', '2', 'J');
618 /* add here more optimizations if needed */
622 for (y
= 0; y
< ConsoleDraw
->SizeY
; y
++)
624 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[',
625 -(int)(ConsoleDraw
->Y
+ y
), ';',
626 -(int)(ConsoleDraw
->X
), 'H');
627 Video
= (PUCHAR
)(ConsoleDraw
+ 1);
628 Video
= &Video
[((ConsoleDraw
->Y
+ y
) * /*DeviceExtension->Columns +*/ ConsoleDraw
->X
) * 2];
629 for (x
= 0; x
< ConsoleDraw
->SizeX
; x
++)
631 AddToSendBuffer(DeviceExtension
, 1, Video
[x
* 2]);
636 DeviceExtension
->LogicalOffset
= (
637 (ConsoleDraw
->CursorY
-1) * DeviceExtension
->Columns
+
638 (ConsoleDraw
->CursorX
-1)) * 2;
639 AddToSendBuffer(DeviceExtension
, 6, ESC
, '[',
640 -(int)(ConsoleDraw
->CursorY
), ';',
641 -(int)(ConsoleDraw
->CursorX
), 'H');
644 AddToSendBuffer(DeviceExtension
, 0);
646 Irp
->IoStatus
.Information
= 0;
647 Status
= STATUS_SUCCESS
;
653 DPRINT1("IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
654 Stack
->Parameters
.DeviceIoControl
.IoControlCode
);
655 /* Call lower driver */
656 IoSkipCurrentIrpStackLocation(Irp
);
657 return IoCallDriver(DeviceExtension
->Common
.LowerDevice
, Irp
);
661 if (!NT_SUCCESS(Status
))
663 /* Don't call blue (if any), as we encountered an error */
664 Irp
->IoStatus
.Status
= Status
;
665 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
670 /* Call lower driver */
671 IoSkipCurrentIrpStackLocation(Irp
);
672 return IoCallDriver(DeviceExtension
->Common
.LowerDevice
, Irp
);