Merge from trunk.
Inform HAL about the switch to graphics modeas late as possible. Fixes
bug 880.
Modified:
branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/dispatch.c
Modified:
branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/videoprt.c
Modified:
branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/videoprt.h
Modified: branches/ros-branch-0_2_8/reactos/subsys/win32k/objects/dc.c
_____
Modified:
branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/dispatch.c
--- branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/dispatch.c
2005-10-17 21:47:17 UTC (rev 18532)
+++ branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/dispatch.c
2005-10-17 21:48:12 UTC (rev 18533)
@@ -18,7 +18,6 @@
* If not, write to the Free Software Foundation,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * $Id$
*/
#include "videoprt.h"
@@ -133,18 +132,6 @@
Irp->IoStatus.Status = STATUS_SUCCESS;
InterlockedIncrement((PLONG)&DeviceExtension->DeviceOpened);
-
- /*
- * Storing the device extension pointer in a static variable is
an
- * ugly hack. Unfortunately, we need it in
VideoPortResetDisplayParameters
- * and HalAcquireDisplayOwnership doesn't allow us to pass a
userdata
- * parameter. On the bright side, the DISPLAY device is opened
- * exclusively, so there can be only one device extension active
at
- * any point in time.
- */
-
- ResetDisplayParametersDeviceExtension = DeviceExtension;
- HalAcquireDisplayOwnership(IntVideoPortResetDisplayParameters);
}
else
{
@@ -264,7 +251,57 @@
return Status;
}
+/*
+ * IntVideoPortWrite
+ *
+ * This is a bit of a hack. We want to take ownership of the display as
late
+ * as possible, just before the switch to graphics mode. Win32k knows
when
+ * this happens, we don't. So we need Win32k to inform us. This could
be done
+ * using an IOCTL, but there's no way of knowing which IOCTL codes are
unused
+ * in the communication between GDI driver and miniport driver. So we
use
+ * IRP_MJ_WRITE as the signal that win32k is ready to switch to
graphics mode,
+ * since we know for certain that there is no read/write activity going
on
+ * between GDI and miniport drivers.
+ * We don't actually need the data that is passed, we just trigger on
the fact
+ * that an IRP_MJ_WRITE was sent.
+ *
+ * Run Level
+ * PASSIVE_LEVEL
+ */
+
NTSTATUS NTAPI
+IntVideoPortDispatchWrite(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS nErrCode;
+
+ DeviceExtension =
(PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ /*
+ * Storing the device extension pointer in a static variable is an
+ * ugly hack. Unfortunately, we need it in
VideoPortResetDisplayParameters
+ * and HalAcquireDisplayOwnership doesn't allow us to pass a
userdata
+ * parameter. On the bright side, the DISPLAY device is opened
+ * exclusively, so there can be only one device extension active at
+ * any point in time.
+ */
+
+ ResetDisplayParametersDeviceExtension = DeviceExtension;
+ HalAcquireDisplayOwnership(IntVideoPortResetDisplayParameters);
+
+ nErrCode = STATUS_SUCCESS;
+ Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
+ Irp->IoStatus.Status = nErrCode;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return nErrCode;
+}
+
+
+NTSTATUS NTAPI
IntVideoPortPnPStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
_____
Modified:
branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/videoprt.c
--- branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/videoprt.c
2005-10-17 21:47:17 UTC (rev 18532)
+++ branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/videoprt.c
2005-10-17 21:48:12 UTC (rev 18533)
@@ -646,6 +646,7 @@
DriverObject->MajorFunction[IRP_MJ_CREATE] =
IntVideoPortDispatchOpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
IntVideoPortDispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
IntVideoPortDispatchDeviceControl;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] =
IntVideoPortDispatchWrite;
DriverObject->DriverUnload = IntVideoPortUnload;
/*
_____
Modified:
branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/videoprt.h
--- branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/videoprt.h
2005-10-17 21:47:17 UTC (rev 18532)
+++ branches/ros-branch-0_2_8/reactos/drivers/video/videoprt/videoprt.h
2005-10-17 21:48:12 UTC (rev 18533)
@@ -148,6 +148,11 @@
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
+NTSTATUS NTAPI
+IntVideoPortDispatchWrite(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
VOID NTAPI
IntVideoPortUnload(PDRIVER_OBJECT DriverObject);
_____
Modified: branches/ros-branch-0_2_8/reactos/subsys/win32k/objects/dc.c
--- branches/ros-branch-0_2_8/reactos/subsys/win32k/objects/dc.c
2005-10-17 21:47:17 UTC (rev 18532)
+++ branches/ros-branch-0_2_8/reactos/subsys/win32k/objects/dc.c
2005-10-17 21:48:12 UTC (rev 18533)
@@ -661,6 +661,61 @@
return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver());
}
+static BOOL FASTCALL
+PrepareVideoPrt()
+{
+ PIRP Irp;
+ NTSTATUS Status;
+ IO_STATUS_BLOCK Iosb;
+ BOOL Prepare = TRUE;
+ ULONG Length = sizeof(BOOL);
+ PIO_STACK_LOCATION StackPtr;
+ LARGE_INTEGER StartOffset;
+ PFILE_OBJECT FileObject = PrimarySurface.VideoFileObject;
+ PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;
+
+ DPRINT("PrepareVideoPrt() called\n");
+
+ KeClearEvent(&PrimarySurface.VideoFileObject->Event);
+
+ ObReferenceObjectByPointer(FileObject, 0, IoFileObjectType,
KernelMode);
+
+ StartOffset.QuadPart = 0;
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
+ DeviceObject,
+ (PVOID) &Prepare,
+ Length,
+ &StartOffset,
+ NULL,
+ &Iosb);
+ if (NULL == Irp)
+ {
+ return FALSE;
+ }
+
+ /* Set up IRP Data */
+ Irp->Tail.Overlay.OriginalFileObject = FileObject;
+ Irp->RequestorMode = KernelMode;
+ Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL;
+ Irp->Overlay.AsynchronousParameters.UserApcContext = NULL;
+ Irp->Flags |= IRP_WRITE_OPERATION;
+
+ /* Setup Stack Data */
+ StackPtr = IoGetNextIrpStackLocation(Irp);
+ StackPtr->FileObject = PrimarySurface.VideoFileObject;
+ StackPtr->Parameters.Write.Key = 0;
+
+ Status = IoCallDriver(DeviceObject, Irp);
+
+ if (STATUS_PENDING == Status)
+ {
+ KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode,
TRUE, 0);
+ Status = Iosb.Status;
+ }
+
+ return NT_SUCCESS(Status);
+}
+
BOOL FASTCALL
IntCreatePrimarySurface()
{
@@ -674,6 +729,11 @@
return FALSE;
}
+ if (! PrepareVideoPrt())
+ {
+ return FALSE;
+ }
+
DPRINT("calling EnableSurface\n");
/* Enable the drawing surface */
PrimarySurface.Handle =
Inform HAL about the switch to graphics mode as late as possible. Fixes
bug 880.
Modified: trunk/reactos/drivers/video/videoprt/dispatch.c
Modified: trunk/reactos/drivers/video/videoprt/videoprt.c
Modified: trunk/reactos/drivers/video/videoprt/videoprt.h
_____
Modified: trunk/reactos/drivers/video/videoprt/dispatch.c
--- trunk/reactos/drivers/video/videoprt/dispatch.c 2005-10-17
20:11:21 UTC (rev 18528)
+++ trunk/reactos/drivers/video/videoprt/dispatch.c 2005-10-17
21:36:23 UTC (rev 18529)
@@ -18,7 +18,6 @@
* If not, write to the Free Software Foundation,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * $Id$
*/
#include "videoprt.h"
@@ -133,18 +132,6 @@
Irp->IoStatus.Status = STATUS_SUCCESS;
InterlockedIncrement((PLONG)&DeviceExtension->DeviceOpened);
-
- /*
- * Storing the device extension pointer in a static variable is
an
- * ugly hack. Unfortunately, we need it in
VideoPortResetDisplayParameters
- * and HalAcquireDisplayOwnership doesn't allow us to pass a
userdata
- * parameter. On the bright side, the DISPLAY device is opened
- * exclusively, so there can be only one device extension active
at
- * any point in time.
- */
-
- ResetDisplayParametersDeviceExtension = DeviceExtension;
- HalAcquireDisplayOwnership(IntVideoPortResetDisplayParameters);
}
else
{
@@ -264,7 +251,57 @@
return Status;
}
+/*
+ * IntVideoPortWrite
+ *
+ * This is a bit of a hack. We want to take ownership of the display as
late
+ * as possible, just before the switch to graphics mode. Win32k knows
when
+ * this happens, we don't. So we need Win32k to inform us. This could
be done
+ * using an IOCTL, but there's no way of knowing which IOCTL codes are
unused
+ * in the communication between GDI driver and miniport driver. So we
use
+ * IRP_MJ_WRITE as the signal that win32k is ready to switch to
graphics mode,
+ * since we know for certain that there is no read/write activity going
on
+ * between GDI and miniport drivers.
+ * We don't actually need the data that is passed, we just trigger on
the fact
+ * that an IRP_MJ_WRITE was sent.
+ *
+ * Run Level
+ * PASSIVE_LEVEL
+ */
+
NTSTATUS NTAPI
+IntVideoPortDispatchWrite(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
+ PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS nErrCode;
+
+ DeviceExtension =
(PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ /*
+ * Storing the device extension pointer in a static variable is an
+ * ugly hack. Unfortunately, we need it in
VideoPortResetDisplayParameters
+ * and HalAcquireDisplayOwnership doesn't allow us to pass a
userdata
+ * parameter. On the bright side, the DISPLAY device is opened
+ * exclusively, so there can be only one device extension active at
+ * any point in time.
+ */
+
+ ResetDisplayParametersDeviceExtension = DeviceExtension;
+ HalAcquireDisplayOwnership(IntVideoPortResetDisplayParameters);
+
+ nErrCode = STATUS_SUCCESS;
+ Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
+ Irp->IoStatus.Status = nErrCode;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return nErrCode;
+}
+
+
+NTSTATUS NTAPI
IntVideoPortPnPStartDevice(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
_____
Modified: trunk/reactos/drivers/video/videoprt/videoprt.c
--- trunk/reactos/drivers/video/videoprt/videoprt.c 2005-10-17
20:11:21 UTC (rev 18528)
+++ trunk/reactos/drivers/video/videoprt/videoprt.c 2005-10-17
21:36:23 UTC (rev 18529)
@@ -646,6 +646,7 @@
DriverObject->MajorFunction[IRP_MJ_CREATE] =
IntVideoPortDispatchOpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
IntVideoPortDispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
IntVideoPortDispatchDeviceControl;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] =
IntVideoPortDispatchWrite;
DriverObject->DriverUnload = IntVideoPortUnload;
/*
_____
Modified: trunk/reactos/drivers/video/videoprt/videoprt.h
--- trunk/reactos/drivers/video/videoprt/videoprt.h 2005-10-17
20:11:21 UTC (rev 18528)
+++ trunk/reactos/drivers/video/videoprt/videoprt.h 2005-10-17
21:36:23 UTC (rev 18529)
@@ -148,6 +148,11 @@
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
+NTSTATUS NTAPI
+IntVideoPortDispatchWrite(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp);
+
VOID NTAPI
IntVideoPortUnload(PDRIVER_OBJECT DriverObject);