Inform HAL about the switch to graphics mode as late as possible. Fixes bug 880.
[reactos.git] / reactos / drivers / video / videoprt / dispatch.c
index 3c11f8e..5d05ba2 100644 (file)
  * If not, write to the Free Software Foundation,
  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
- * $Id$
  */
 
 #include "videoprt.h"
 
 /* EXTERNAL FUNCTIONS *********************************************************/
 
-typedef PVOID PHAL_RESET_DISPLAY_PARAMETERS;
-VOID STDCALL HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters);
-VOID STDCALL HalReleaseDisplayOwnership();
+VOID NTAPI HalAcquireDisplayOwnership(IN PHAL_RESET_DISPLAY_PARAMETERS ResetDisplayParameters);
+VOID NTAPI HalReleaseDisplayOwnership();
 
 /* GLOBAL VARIABLES ***********************************************************/
 
@@ -39,7 +37,7 @@ PVIDEO_PORT_DEVICE_EXTENSION ResetDisplayParametersDeviceExtension = NULL;
  * Reset display to blue screen
  */
 
-BOOLEAN STDCALL
+BOOLEAN NTAPI
 IntVideoPortResetDisplayParameters(ULONG Columns, ULONG Rows)
 {
    PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
@@ -64,7 +62,7 @@ IntVideoPortResetDisplayParameters(ULONG Columns, ULONG Rows)
    return FALSE;
 }
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject)
@@ -97,7 +95,7 @@ IntVideoPortAddDevice(
  *    PASSIVE_LEVEL
  */
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortDispatchOpen(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
@@ -134,18 +132,6 @@ IntVideoPortDispatchOpen(
       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
    {
@@ -167,7 +153,7 @@ IntVideoPortDispatchOpen(
  *    PASSIVE_LEVEL
  */
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortDispatchClose(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
@@ -199,7 +185,7 @@ IntVideoPortDispatchClose(
  *    PASSIVE_LEVEL
  */
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortDispatchDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
@@ -265,7 +251,57 @@ IntVideoPortDispatchDeviceControl(
    return Status;
 }
 
-NTSTATUS STDCALL
+/*
+ * 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)
@@ -353,7 +389,7 @@ IntVideoPortPnPStartDevice(
 
 
 NTSTATUS
-STDCALL
+NTAPI
 IntVideoPortForwardIrpAndWaitCompletionRoutine(
     PDEVICE_OBJECT Fdo,
     PIRP Irp,
@@ -369,7 +405,7 @@ IntVideoPortForwardIrpAndWaitCompletionRoutine(
 
 
 NTSTATUS
-STDCALL
+NTAPI
 IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
 {
    KEVENT Event;
@@ -391,7 +427,7 @@ IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
@@ -443,7 +479,7 @@ IntVideoPortDispatchPnp(
    return Status;
 }
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortDispatchCleanup(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
@@ -460,7 +496,7 @@ IntVideoPortDispatchCleanup(
    return STATUS_SUCCESS;
 }
 
-NTSTATUS STDCALL
+NTSTATUS NTAPI
 IntVideoPortDispatchPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
@@ -468,7 +504,7 @@ IntVideoPortDispatchPower(
    return STATUS_NOT_IMPLEMENTED;
 }
 
-VOID STDCALL
+VOID NTAPI
 IntVideoPortUnload(PDRIVER_OBJECT DriverObject)
 {
 }