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);