-# $Id: makefile,v 1.9 2001/08/21 20:13:12 chorns Exp $
+# $Id: makefile,v 1.10 2003/02/15 19:16:33 gvg Exp $
PATH_TO_TOP = ../../../..
TARGET_NAME = vgamp
-TARGET_DDKLIBS = vidport.a
+TARGET_DDKLIBS = videoprt.a
TARGET_OBJECTS = \
initvga.o \
--- /dev/null
+vidport.coff
+*.o
+*.sym
+*.sys
--- /dev/null
+/* $Id: videoprt.c,v 1.1 2003/02/15 19:16:32 gvg Exp $
+ *
+ * VideoPort driver
+ * Written by Rex Jolliff
+ *
+ * FIXME:
+ * There are two ugly and temporary hacks in this file, to get the VMware driver to
+ * work.
+ * First, the miniport driver is allowed to call VideoPortInitialize() multiple times.
+ * VideoPortInitialize() will create a device and then call the miniport's
+ * HwFindAdapter(). If that call returns with an error code, the device will be
+ * deleted. The next time VideoPortInitialize() is called, it will be create a
+ * new device with the same name as the first time. The first device was deleted so
+ * this shouldn't be a problem, the device is created successfully. Initialization
+ * then continues.
+ * The problems start when it's time to start the device. When the driver is opened,
+ * the caller will receive a pointer to the FIRST device, the one which was later
+ * deleted. This is propably due to a problem in the Io subsystem which needs to
+ * be investigated. To get around this, a pointer is kept to the last successfully
+ * opened device (pdoLastOpened) and this device is used instead of the pointer
+ * passed in.
+ * The second problem has to do with resources. The miniport driver will call
+ * VideoPortGetDeviceBase() to map a physical address to a virtual address. Later,
+ * it will call VideoPortMapMemory() with the same physical address. It should
+ * map to the same virtual address, but I couldn't get this to work at the moment.
+ * So, as a workaround, a maximum of 2 physical addresses with their corresponding
+ * virtual addresses are kept in the device extension block. They are filled by
+ * VideoPortGetDeviceBase() and looked-up by VideoPortMapMemory().
+ */
+
+#include <errors.h>
+#include <ddk/ntddk.h>
+#include <ddk/ntddvid.h>
+
+#include "../../../ntoskrnl/include/internal/v86m.h"
+
+#include "videoprt.h"
+
+#define NDEBUG
+#include <debug.h>
+
+#define VERSION "0.0.0"
+
+static VOID STDCALL VidStartIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
+static NTSTATUS STDCALL VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp);
+static NTSTATUS STDCALL VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
+
+static BOOLEAN CsrssInitialized = FALSE;
+static HANDLE CsrssHandle = 0;
+static struct _EPROCESS* Csrss = NULL;
+
+/* FIXME: see file header */
+static PDEVICE_OBJECT pdoLastOpened;
+static PVOID Virt7efc0000;
+static PVOID Virt7ffc0000;
+
+PBYTE ReturnCsrssAddress(void)
+{
+ DPRINT("ReturnCsrssAddress()\n");
+ return (PBYTE)Csrss;
+}
+
+// ------------------------------------------------------- Public Interface
+
+// DriverEntry
+//
+// DESCRIPTION:
+// This function initializes the driver.
+//
+// RUN LEVEL:
+// PASSIVE_LEVEL
+//
+// ARGUMENTS:
+// IN PDRIVER_OBJECT DriverObject System allocated Driver Object
+// for this driver
+// IN PUNICODE_STRING RegistryPath Name of registry driver service
+// key
+//
+// RETURNS:
+// NTSTATUS
+
+STDCALL NTSTATUS
+DriverEntry(IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
+{
+ DPRINT("DriverEntry()\n");
+ return(STATUS_SUCCESS);
+}
+
+VOID
+VideoPortDebugPrint(IN ULONG DebugPrintLevel,
+ IN PCHAR DebugMessage, ...)
+{
+ char Buffer[256];
+ va_list ap;
+
+/*
+ if (DebugPrintLevel > InternalDebugLevel)
+ return;
+*/
+ va_start (ap, DebugMessage);
+ vsprintf (Buffer, DebugMessage, ap);
+ va_end (ap);
+
+ DbgPrint (Buffer);
+}
+
+VP_STATUS
+STDCALL
+VideoPortDisableInterrupt(IN PVOID HwDeviceExtension)
+{
+ DPRINT("VideoPortDisableInterrupt\n");
+ UNIMPLEMENTED;
+}
+
+VP_STATUS
+STDCALL
+VideoPortEnableInterrupt(IN PVOID HwDeviceExtension)
+{
+ DPRINT("VideoPortEnableInterrupt\n");
+ UNIMPLEMENTED;
+}
+
+VOID
+STDCALL
+VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension,
+ IN PVOID MappedAddress)
+{
+ DPRINT1("VideoPortFreeDeviceBase not implemented\n");
+}
+
+ULONG
+STDCALL
+VideoPortGetBusData(IN PVOID HwDeviceExtension,
+ IN BUS_DATA_TYPE BusDataType,
+ IN ULONG SlotNumber,
+ OUT PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length)
+{
+ DPRINT("VideoPortGetBusData\n");
+ return HalGetBusDataByOffset(BusDataType,
+ 0,
+ SlotNumber,
+ Buffer,
+ Offset,
+ Length);
+}
+
+UCHAR
+STDCALL
+VideoPortGetCurrentIrql(VOID)
+{
+ DPRINT("VideoPortGetCurrentIrql\n");
+ return KeGetCurrentIrql();
+}
+
+PVOID
+STDCALL
+VideoPortGetDeviceBase(IN PVOID HwDeviceExtension,
+ IN PHYSICAL_ADDRESS IoAddress,
+ IN ULONG NumberOfUchars,
+ IN UCHAR InIoSpace)
+{
+ PHYSICAL_ADDRESS TranslatedAddress;
+ PVOID Virtual;
+ ULONG AddressSpace;
+ PVIDEOPORT_EXTENSION_DATA ExtensionData =
+ MPExtensionToVPExtension(HwDeviceExtension);
+
+ DPRINT("VideoPortGetDeviceBase\n");
+ AddressSpace = (InIoSpace ? 1 : 0);
+
+ if (HalTranslateBusAddress(PCIBus, 0, IoAddress, &AddressSpace, &TranslatedAddress))
+ {
+ if (AddressSpace)
+ {
+ return (PVOID)(DWORD)(TranslatedAddress.QuadPart);
+ }
+ else
+ {
+ Virtual = MmMapIoSpace(TranslatedAddress, NumberOfUchars, MmNonCached);
+ /* FIXME: see file header */
+ DPRINT("Mapped 0x%08x to 0x%08x\n", IoAddress.u.LowPart, Virtual);
+ if (0x7efc0000 == IoAddress.u.LowPart)
+ {
+ Virt7efc0000 = Virtual;
+ }
+ if (0x7ffc0000 == IoAddress.u.LowPart)
+ {
+ Virt7ffc0000 = Virtual;
+ }
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+VP_STATUS
+STDCALL
+VideoPortGetDeviceData(IN PVOID HwDeviceExtension,
+ IN VIDEO_DEVICE_DATA_TYPE DeviceDataType,
+ IN PMINIPORT_QUERY_DEVICE_ROUTINE CallbackRoutine,
+ IN PVOID Context)
+{
+ DPRINT("VideoPortGetDeviceData\n");
+ UNIMPLEMENTED;
+}
+
+VP_STATUS
+STDCALL
+VideoPortGetAccessRanges(IN PVOID HwDeviceExtension,
+ IN ULONG NumRequestedResources,
+ IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
+ IN ULONG NumAccessRanges,
+ IN PVIDEO_ACCESS_RANGE AccessRanges,
+ IN PVOID VendorId,
+ IN PVOID DeviceId,
+ IN PULONG Slot)
+{
+ DPRINT("VideoPortGetAccessRanges\n");
+ UNIMPLEMENTED;
+}
+
+VP_STATUS
+STDCALL
+VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension,
+ IN PWSTR ParameterName,
+ IN UCHAR IsParameterFileName,
+ IN PMINIPORT_GET_REGISTRY_ROUTINE GetRegistryRoutine,
+ IN PVOID Context)
+{
+ DPRINT("VideoPortGetRegistryParameters\n");
+ UNIMPLEMENTED;
+}
+
+ULONG STDCALL
+VideoPortInitialize(IN PVOID Context1,
+ IN PVOID Context2,
+ IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData,
+ IN PVOID HwContext)
+{
+ UCHAR Again;
+ WCHAR DeviceBuffer[20];
+ WCHAR SymlinkBuffer[20];
+ NTSTATUS Status;
+ PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1;
+ PDEVICE_OBJECT MPDeviceObject;
+ VIDEO_PORT_CONFIG_INFO ConfigInfo;
+ PVIDEOPORT_EXTENSION_DATA ExtensionData;
+ ULONG DeviceNumber = 0;
+ UNICODE_STRING DeviceName;
+ UNICODE_STRING SymlinkName;
+ CLIENT_ID Cid;
+
+ DPRINT("VideoPortInitialize\n");
+
+ /* Build Dispatch table from passed data */
+ MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO;
+
+ /* Create a unicode device name */
+ Again = FALSE;
+ do
+ {
+ swprintf(DeviceBuffer, L"\\Device\\Video%lu", DeviceNumber);
+ RtlInitUnicodeString(&DeviceName, DeviceBuffer);
+
+ /* Create the device */
+ Status = IoCreateDevice(MPDriverObject,
+ HwInitializationData->HwDeviceExtensionSize +
+ sizeof(VIDEOPORT_EXTENSION_DATA),
+ &DeviceName,
+ FILE_DEVICE_VIDEO,
+ 0,
+ TRUE,
+ &MPDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoCreateDevice call failed with status 0x%08x\n", Status);
+ return Status;
+ }
+
+ MPDriverObject->DeviceObject = MPDeviceObject;
+
+ /* initialize the miniport drivers dispatch table */
+ MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpenClose;
+ MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchOpenClose;
+ MPDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatchDeviceControl;
+
+ /* create symbolic link "\??\DISPLAYx" */
+ swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber+1);
+ RtlInitUnicodeString (&SymlinkName,
+ SymlinkBuffer);
+ IoCreateSymbolicLink (&SymlinkName,
+ &DeviceName);
+
+ ExtensionData =
+ (PVIDEOPORT_EXTENSION_DATA) MPDeviceObject->DeviceExtension;
+ ExtensionData->DeviceObject = MPDeviceObject;
+ ExtensionData->HwInitialize = HwInitializationData->HwInitialize;
+
+ /* Set the buffering strategy here... */
+ /* If you change this, remember to change VidDispatchDeviceControl too */
+ MPDeviceObject->Flags |= DO_BUFFERED_IO;
+
+ RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO));
+ ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO);
+ ConfigInfo.AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
+ /* Call HwFindAdapter entry point */
+ /* FIXME: Need to figure out what string to pass as param 3 */
+ Status = HwInitializationData->HwFindAdapter(VPExtensionToMPExtension(ExtensionData),
+ Context2,
+ NULL,
+ &ConfigInfo,
+ &Again);
+ if (NO_ERROR != Status)
+ {
+ DPRINT("HwFindAdapter call failed with error %d\n", Status);
+ IoDeleteDevice(MPDeviceObject);
+ IoDeleteSymbolicLink(&SymlinkName);
+
+ return Status;
+ }
+ /* FIXME: see file header */
+ pdoLastOpened = MPDeviceObject;
+ DPRINT("Setting last opened device to 0x%08x\n", pdoLastOpened);
+
+ /* FIXME: Allocate hardware resources for device */
+
+ /* Allocate interrupt for device */
+ if (HwInitializationData->HwInterrupt != NULL &&
+ !(ConfigInfo.BusInterruptLevel == 0 &&
+ ConfigInfo.BusInterruptVector == 0))
+ {
+#if 0
+ ExtensionData->IRQL = ConfigInfo.BusInterruptLevel;
+ ExtensionData->InterruptLevel =
+ HalGetInterruptVector(ConfigInfo.AdapterInterfaceType,
+ ConfigInfo.SystemIoBusNumber,
+ ConfigInfo.BusInterruptLevel,
+ ConfigInfo.BusInterruptVector,
+ &ExtensionData->IRQL,
+ &ExtensionData->Affinity);
+ KeInitializeSpinLock(&ExtensionData->InterruptSpinLock);
+ Status = IoConnectInterrupt(&ExtensionData->InterruptObject,
+ (PKSERVICE_ROUTINE)
+ HwInitializationData->HwInterrupt,
+ VPExtensionToMPExtension(ExtensionData),
+ &ExtensionData->InterruptSpinLock,
+ ExtensionData->InterruptLevel,
+ ExtensionData->IRQL,
+ ExtensionData->IRQL,
+ ConfigInfo.InterruptMode,
+ FALSE,
+ ExtensionData->Affinity,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoConnectInterrupt failed with status 0x%08x\n", Status);
+ IoDeleteDevice(MPDeviceObject);
+
+ return Status;
+ }
+#endif
+ }
+ DeviceNumber++;
+ }
+ while (Again);
+
+ /* FIXME: initialize timer routine for MP Driver */
+ if (HwInitializationData->HwTimer != NULL)
+ {
+ Status = IoInitializeTimer(MPDeviceObject,
+ (PIO_TIMER_ROUTINE)
+ HwInitializationData->HwTimer,
+ VPExtensionToMPExtension(ExtensionData));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status);
+
+ if (HwInitializationData->HwInterrupt != NULL)
+ {
+ IoDisconnectInterrupt(ExtensionData->InterruptObject);
+ }
+ IoDeleteDevice(MPDeviceObject);
+
+ return Status;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+VP_STATUS STDCALL
+VideoPortInt10(IN PVOID HwDeviceExtension,
+ IN PVIDEO_X86_BIOS_ARGUMENTS BiosArguments)
+{
+ KV86M_REGISTERS Regs;
+ NTSTATUS Status;
+
+ DPRINT("VideoPortInt10\n");
+ KeAttachProcess(Csrss);
+
+ memset(&Regs, 0, sizeof(Regs));
+ Regs.Eax = BiosArguments->Eax;
+ Regs.Ebx = BiosArguments->Ebx;
+ Regs.Ecx = BiosArguments->Ecx;
+ Regs.Edx = BiosArguments->Edx;
+ Regs.Esi = BiosArguments->Esi;
+ Regs.Edi = BiosArguments->Edi;
+ Regs.Ebp = BiosArguments->Ebp;
+ Status = Ke386CallBios(0x10, &Regs);
+
+ KeDetachProcess();
+
+ return(Status);
+}
+
+VOID
+STDCALL
+VideoPortLogError(IN PVOID HwDeviceExtension,
+ IN PVIDEO_REQUEST_PACKET Vrp OPTIONAL,
+ IN VP_STATUS ErrorCode,
+ IN ULONG UniqueId)
+{
+ DPRINT("VideoPortLogError\n");
+ UNIMPLEMENTED;
+}
+
+VP_STATUS
+STDCALL
+VideoPortMapBankedMemory(IN PVOID HwDeviceExtension,
+ IN PHYSICAL_ADDRESS PhysicalAddress,
+ IN PULONG Length,
+ IN PULONG InIoSpace,
+ OUT PVOID *VirtualAddress,
+ IN ULONG BankLength,
+ IN UCHAR ReadWriteBank,
+ IN PBANKED_SECTION_ROUTINE BankRoutine,
+ IN PVOID Context)
+{
+ DPRINT("VideoPortMapBankedMemory\n");
+ UNIMPLEMENTED;
+}
+
+VP_STATUS
+STDCALL
+VideoPortMapMemory(IN PVOID HwDeviceExtension,
+ IN PHYSICAL_ADDRESS PhysicalAddress,
+ IN PULONG Length,
+ IN PULONG InIoSpace,
+ OUT PVOID *VirtualAddress)
+{
+ PHYSICAL_ADDRESS TranslatedAddress;
+ ULONG AddressSpace;
+ PVIDEOPORT_EXTENSION_DATA ExtensionData =
+ MPExtensionToVPExtension(HwDeviceExtension);
+
+ DPRINT("VideoPortMapMemory\n");
+
+ /* FIXME: see file header */
+ if (0x7efc0000 == PhysicalAddress.u.LowPart)
+ {
+ DPRINT("Using saved mapping for 0x7efc0000\n");
+ *VirtualAddress = Virt7efc0000;
+ return STATUS_SUCCESS;
+ }
+ if (0x7ffc0000 == PhysicalAddress.u.LowPart)
+ {
+ DPRINT("Using saved mapping for 0x7ffc0000\n");
+ *VirtualAddress = Virt7ffc0000;
+ return STATUS_SUCCESS;
+ }
+
+ AddressSpace = (*InIoSpace ? 1 : 0);
+
+ if (HalTranslateBusAddress(PCIBus, 0, PhysicalAddress, &AddressSpace, &TranslatedAddress))
+ {
+ if (AddressSpace)
+ {
+ *VirtualAddress = (PVOID)(DWORD)(TranslatedAddress.QuadPart);
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ *VirtualAddress = MmMapIoSpace(TranslatedAddress, *Length, MmNonCached);
+ return NULL != *VirtualAddress ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+}
+
+UCHAR
+STDCALL
+VideoPortReadPortUchar(IN PUCHAR Port)
+{
+ DPRINT("VideoPortReadPortUchar\n");
+ return READ_PORT_UCHAR(Port);
+}
+
+USHORT
+STDCALL
+VideoPortReadPortUshort(IN PUSHORT Port)
+{
+ DPRINT("VideoPortReadPortUshort\n");
+ return READ_PORT_USHORT(Port);
+}
+
+ULONG
+STDCALL
+VideoPortReadPortUlong(IN PULONG Port)
+{
+ DPRINT("VideoPortReadPortUlong\n");
+ return READ_PORT_ULONG(Port);
+}
+
+VOID
+STDCALL
+VideoPortReadPortBufferUchar(IN PUCHAR Port,
+ OUT PUCHAR Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortReadPortBufferUchar\n");
+ READ_PORT_BUFFER_UCHAR(Port, Buffer, Count);
+}
+
+VOID
+STDCALL
+VideoPortReadPortBufferUshort(IN PUSHORT Port,
+ OUT PUSHORT Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortReadPortBufferUshort\n");
+ READ_PORT_BUFFER_USHORT(Port, Buffer, Count);
+}
+
+VOID
+STDCALL
+VideoPortReadPortBufferUlong(IN PULONG Port,
+ OUT PULONG Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortReadPortBufferUlong\n");
+ READ_PORT_BUFFER_ULONG(Port, Buffer, Count);
+}
+
+UCHAR
+STDCALL
+VideoPortReadRegisterUchar(IN PUCHAR Register)
+{
+ DPRINT("VideoPortReadPortRegisterUchar\n");
+ return READ_REGISTER_UCHAR(Register);
+}
+
+USHORT
+STDCALL
+VideoPortReadRegisterUshort(IN PUSHORT Register)
+{
+ DPRINT("VideoPortReadPortRegisterUshort\n");
+ return READ_REGISTER_USHORT(Register);
+}
+
+ULONG
+STDCALL
+VideoPortReadRegisterUlong(IN PULONG Register)
+{
+ DPRINT("VideoPortReadPortRegisterUlong\n");
+ return READ_REGISTER_ULONG(Register);
+}
+
+VOID
+STDCALL
+VideoPortReadRegisterBufferUchar(IN PUCHAR Register,
+ OUT PUCHAR Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortReadPortRegisterBufferUchar\n");
+ READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
+}
+
+VOID
+STDCALL
+VideoPortReadRegisterBufferUshort(IN PUSHORT Register,
+ OUT PUSHORT Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortReadPortRegisterBufferUshort\n");
+ READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
+}
+
+VOID
+STDCALL
+VideoPortReadRegisterBufferUlong(IN PULONG Register,
+ OUT PULONG Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortReadPortRegisterBufferUlong\n");
+ READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
+}
+
+BOOLEAN
+STDCALL
+VideoPortScanRom(IN PVOID HwDeviceExtension,
+ IN PUCHAR RomBase,
+ IN ULONG RomLength,
+ IN PUCHAR String)
+{
+ DPRINT("VideoPortScanRom\n");
+ UNIMPLEMENTED;
+}
+
+ULONG
+STDCALL
+VideoPortSetBusData(IN PVOID HwDeviceExtension,
+ IN BUS_DATA_TYPE BusDataType,
+ IN ULONG SlotNumber,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length)
+{
+ DPRINT("VideoPortSetBusData\n");
+ return HalSetBusDataByOffset(BusDataType,
+ 0,
+ SlotNumber,
+ Buffer,
+ Offset,
+ Length);
+}
+
+VP_STATUS
+STDCALL
+VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension,
+ IN PWSTR ValueName,
+ IN PVOID ValueData,
+ IN ULONG ValueLength)
+{
+ DPRINT1("VideoPortSetRegistryParameters not implemented\n");
+ return NO_ERROR;
+}
+
+VP_STATUS
+STDCALL
+VideoPortSetTrappedEmulatorPorts(IN PVOID HwDeviceExtension,
+ IN ULONG NumAccessRanges,
+ IN PVIDEO_ACCESS_RANGE AccessRange)
+{
+ DPRINT("VideoPortSetTrappedEmulatorPorts\n");
+ UNIMPLEMENTED;
+}
+
+VOID
+STDCALL
+VideoPortStartTimer(IN PVOID HwDeviceExtension)
+{
+ PVIDEOPORT_EXTENSION_DATA ExtensionData =
+ MPExtensionToVPExtension(HwDeviceExtension);
+
+ DPRINT("VideoPortStartTimer\n");
+ IoStartTimer(ExtensionData->DeviceObject);
+}
+
+VOID
+STDCALL
+VideoPortStopTimer(IN PVOID HwDeviceExtension)
+{
+ PVIDEOPORT_EXTENSION_DATA ExtensionData =
+ MPExtensionToVPExtension(HwDeviceExtension);
+
+ DPRINT("VideoPortStopTimer\n");
+ IoStopTimer(ExtensionData->DeviceObject);
+}
+
+BOOLEAN
+STDCALL
+VideoPortSynchronizeExecution(IN PVOID HwDeviceExtension,
+ IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
+ IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
+ OUT PVOID Context)
+{
+ DPRINT("VideoPortSynchronizeExecution\n");
+ UNIMPLEMENTED;
+}
+
+VP_STATUS
+STDCALL
+VideoPortUnmapMemory(IN PVOID HwDeviceExtension,
+ IN PVOID VirtualAddress,
+ IN HANDLE ProcessHandle)
+{
+ DPRINT1("VideoPortUnmapMemory not implemented\n");
+ return NO_ERROR;
+}
+
+VP_STATUS
+STDCALL
+VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension,
+ IN ULONG NumAccessRanges,
+ IN PVIDEO_ACCESS_RANGE AccessRanges)
+{
+ DPRINT1("VideoPortVerifyAccessRanges not implemented\n");
+ return NO_ERROR;
+}
+
+VOID
+STDCALL
+VideoPortWritePortUchar(IN PUCHAR Port,
+ IN UCHAR Value)
+{
+ DPRINT("VideoPortWritePortUchar\n");
+ WRITE_PORT_UCHAR(Port, Value);
+}
+
+VOID
+STDCALL
+VideoPortWritePortUshort(IN PUSHORT Port,
+ IN USHORT Value)
+{
+ DPRINT("VideoPortWritePortUshort\n");
+ WRITE_PORT_USHORT(Port, Value);
+}
+
+VOID
+STDCALL
+VideoPortWritePortUlong(IN PULONG Port,
+ IN ULONG Value)
+{
+ DPRINT("VideoPortWritePortUlong\n");
+ WRITE_PORT_ULONG(Port, Value);
+}
+
+VOID
+STDCALL
+VideoPortWritePortBufferUchar(IN PUCHAR Port,
+ IN PUCHAR Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortWritePortBufferUchar\n");
+ WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count);
+}
+
+VOID
+STDCALL
+VideoPortWritePortBufferUshort(IN PUSHORT Port,
+ IN PUSHORT Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortWritePortBufferUshort\n");
+ WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count);
+}
+
+VOID
+STDCALL
+VideoPortWritePortBufferUlong(IN PULONG Port,
+ IN PULONG Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortWritePortBufferUlong\n");
+ WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count);
+}
+
+VOID
+STDCALL
+VideoPortWriteRegisterUchar(IN PUCHAR Register,
+ IN UCHAR Value)
+{
+ DPRINT("VideoPortWriteRegisterUchar\n");
+ WRITE_REGISTER_UCHAR(Register, Value);
+}
+
+VOID
+STDCALL
+VideoPortWriteRegisterUshort(IN PUSHORT Register,
+ IN USHORT Value)
+{
+ DPRINT("VideoPortWriteRegisterUshort\n");
+ WRITE_REGISTER_USHORT(Register, Value);
+}
+
+VOID
+STDCALL
+VideoPortWriteRegisterUlong(IN PULONG Register,
+ IN ULONG Value)
+{
+ DPRINT("VideoPortWriteRegisterUlong\n");
+ WRITE_REGISTER_ULONG(Register, Value);
+}
+
+VOID
+STDCALL
+VideoPortWriteRegisterBufferUchar(IN PUCHAR Register,
+ IN PUCHAR Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortWriteRegisterBufferUchar\n");
+ WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
+}
+
+VOID STDCALL
+VideoPortWriteRegisterBufferUshort(IN PUSHORT Register,
+ IN PUSHORT Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortWriteRegisterBufferUshort\n");
+ WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
+}
+
+VOID STDCALL
+VideoPortWriteRegisterBufferUlong(IN PULONG Register,
+ IN PULONG Buffer,
+ IN ULONG Count)
+{
+ DPRINT("VideoPortWriteRegisterBufferUlong\n");
+ WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
+}
+
+VOID STDCALL
+VideoPortZeroDeviceMemory(OUT PVOID Destination,
+ IN ULONG Length)
+{
+ DPRINT("VideoPortZeroDeviceMemory\n");
+ UNIMPLEMENTED;
+}
+
+
+// ------------------------------------------- Nondiscardable statics
+
+// VidDispatchOpenClose
+//
+// DESCRIPTION:
+// Answer requests for Open/Close calls: a null operation
+//
+// RUN LEVEL:
+// PASSIVE_LEVEL
+//
+// ARGUMENTS:
+// Standard dispatch arguments
+//
+// RETURNS:
+// NTSTATUS
+//
+
+static NTSTATUS STDCALL
+VidDispatchOpenClose(IN PDEVICE_OBJECT pDO,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpStack;
+ PVIDEOPORT_EXTENSION_DATA ExtensionData;
+
+ DPRINT("VidDispatchOpenClose() called\n");
+
+ /* FIXME: see file header */
+ DPRINT("Using device 0x%08x instead of 0x%08x\n", pdoLastOpened, pDO);
+ pDO = pdoLastOpened;
+ IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+ if (IrpStack->MajorFunction == IRP_MJ_CREATE &&
+ CsrssInitialized == FALSE)
+ {
+ DPRINT("Referencing CSRSS\n");
+ Csrss = PsGetCurrentProcess();
+ CsrssInitialized = TRUE;
+ DPRINT("Csrss %p\n", Csrss);
+ ExtensionData = (PVIDEOPORT_EXTENSION_DATA) pDO->DeviceExtension;
+ if (ExtensionData->HwInitialize(VPExtensionToMPExtension(ExtensionData)))
+ {
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ }
+ }
+ else
+ {
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+
+ Irp->IoStatus.Information = FILE_OPENED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+// VidStartIo
+//
+// DESCRIPTION:
+// Get the next requested I/O packet started
+//
+// RUN LEVEL:
+// DISPATCH_LEVEL
+//
+// ARGUMENTS:
+// Dispatch routine standard arguments
+//
+// RETURNS:
+// NTSTATUS
+//
+
+static VOID STDCALL
+VidStartIo(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ DPRINT("VidStartIo\n");
+ UNIMPLEMENTED;
+}
+
+// VidDispatchDeviceControl
+//
+// DESCRIPTION:
+// Answer requests for device control calls
+//
+// RUN LEVEL:
+// PASSIVE_LEVEL
+//
+// ARGUMENTS:
+// Standard dispatch arguments
+//
+// RETURNS:
+// NTSTATUS
+//
+
+static NTSTATUS STDCALL
+VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpStack;
+ PVIDEO_REQUEST_PACKET vrp;
+
+ DPRINT("VidDispatchDeviceControl\n");
+ /* FIXME: See file header */
+ DPRINT("Using device 0x%08x instead of 0x%08x\n", pdoLastOpened, DeviceObject);
+ DeviceObject = pdoLastOpened;
+ IrpStack = IoGetCurrentIrpStackLocation(Irp);
+
+ // Translate the IRP to a VRP
+ vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET));
+ vrp->StatusBlock = ExAllocatePool(PagedPool, sizeof(STATUS_BLOCK));
+ vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
+
+ // We're assuming METHOD_BUFFERED
+ vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
+ vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
+ vrp->OutputBuffer = Irp->UserBuffer;
+ vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
+
+ // Call the Miniport Driver with the VRP
+ DeviceObject->DriverObject->DriverStartIo(VPExtensionToMPExtension(DeviceObject->DeviceExtension), (PIRP)vrp);
+
+ // Translate the VRP back into the IRP for OutputBuffer
+ Irp->UserBuffer = vrp->OutputBuffer;
+ IrpStack->Parameters.DeviceIoControl.OutputBufferLength = vrp->OutputBufferLength;
+ Irp->IoStatus.Status = vrp->StatusBlock->Status;
+ Irp->IoStatus.Information = vrp->StatusBlock->Information;
+
+ // Free the VRP
+ ExFreePool(vrp->StatusBlock);
+ ExFreePool(vrp);
+
+ return STATUS_SUCCESS;
+}
--- /dev/null
+; $Id: videoprt.def,v 1.1 2003/02/15 19:16:32 gvg Exp $
+;
+; vidport.def - export definition file for ReactOS
+;
+EXPORTS
+ReturnCsrssAddress
+VideoPortCompareMemory@12
+VideoPortDebugPrint
+VideoPortDisableInterrupt@4
+VideoPortEnableInterrupt@4
+VideoPortFreeDeviceBase@8
+VideoPortGetBusData@24
+VideoPortGetCurrentIrql@0
+VideoPortGetDeviceBase@20
+VideoPortGetDeviceData@16
+VideoPortGetAccessRanges@32
+VideoPortGetRegistryParameters@20
+VideoPortInitialize@16
+VideoPortInt10@8
+VideoPortLogError@16
+VideoPortMapBankedMemory@40
+VideoPortMapMemory@24
+VideoPortMoveMemory@12
+VideoPortReadPortUchar@4
+VideoPortReadPortUshort@4
+VideoPortReadPortUlong@4
+VideoPortReadPortBufferUchar@12
+VideoPortReadPortBufferUshort@12
+VideoPortReadPortBufferUlong@12
+VideoPortReadRegisterUchar@4
+VideoPortReadRegisterUshort@4
+VideoPortReadRegisterUlong@4
+VideoPortReadRegisterBufferUchar@12
+VideoPortReadRegisterBufferUshort@12
+VideoPortReadRegisterBufferUlong@12
+VideoPortScanRom@16
+VideoPortSetBusData@24
+VideoPortSetRegistryParameters@16
+VideoPortSetTrappedEmulatorPorts@12
+VideoPortStallExecution@4
+VideoPortStartTimer@4
+VideoPortStopTimer@4
+VideoPortSynchronizeExecution@16
+VideoPortUnmapMemory@12
+VideoPortVerifyAccessRanges@12
+VideoPortWritePortUchar@8
+VideoPortWritePortUshort@8
+VideoPortWritePortUlong@8
+VideoPortWritePortBufferUchar@12
+VideoPortWritePortBufferUshort@12
+VideoPortWritePortBufferUlong@12
+VideoPortWriteRegisterUchar@8
+VideoPortWriteRegisterUshort@8
+VideoPortWriteRegisterUlong@8
+VideoPortWriteRegisterBufferUchar@12
+VideoPortWriteRegisterBufferUshort@12
+VideoPortWriteRegisterBufferUlong@12
+VideoPortZeroMemory@8
+VideoPortZeroDeviceMemory@8
+
--- /dev/null
+; $Id: videoprt.edf,v 1.1 2003/02/15 19:16:32 gvg Exp $
+;
+; vidport.def - export definition file for ReactOS
+;
+EXPORTS
+ReturnCsrssAddress
+VideoPortCompareMemory=NTOSKRNL.RtlCompareMemory
+VideoPortDebugPrint
+VideoPortDisableInterrupt=VideoPortDisableInterrupt@4
+VideoPortEnableInterrupt=VideoPortEnableInterrupt@4
+VideoPortFreeDeviceBase=VideoPortFreeDeviceBase@8
+VideoPortGetBusData=VideoPortGetBusData@24
+VideoPortGetCurrentIrql=VideoPortGetCurrentIrql@0
+VideoPortGetDeviceBase=VideoPortGetDeviceBase@20
+VideoPortGetDeviceData=VideoPortGetDeviceData@16
+VideoPortGetAccessRanges=VideoPortGetAccessRanges@32
+VideoPortGetRegistryParameters=VideoPortGetRegistryParameters@20
+VideoPortInitialize=VideoPortInitialize@16
+VideoPortInt10=VideoPortInt10@8
+VideoPortLogError=VideoPortLogError@16
+VideoPortMapBankedMemory=VideoPortMapBankedMemory@40
+VideoPortMapMemory=VideoPortMapMemory@24
+VideoPortMoveMemory=NTOSKRNL.RtlMoveMemory
+VideoPortReadPortUchar=VideoPortReadPortUchar@4
+VideoPortReadPortUshort=VideoPortReadPortUshort@4
+VideoPortReadPortUlong=VideoPortReadPortUlong@4
+VideoPortReadPortBufferUchar=VideoPortReadPortBufferUchar@12
+VideoPortReadPortBufferUshort=VideoPortReadPortBufferUshort@12
+VideoPortReadPortBufferUlong=VideoPortReadPortBufferUlong@12
+VideoPortReadRegisterUchar=VideoPortReadRegisterUchar@4
+VideoPortReadRegisterUshort=VideoPortReadRegisterUshort@4
+VideoPortReadRegisterUlong=VideoPortReadRegisterUlong@4
+VideoPortReadRegisterBufferUchar=VideoPortReadRegisterBufferUchar@12
+VideoPortReadRegisterBufferUshort=VideoPortReadRegisterBufferUshort@12
+VideoPortReadRegisterBufferUlong=VideoPortReadRegisterBufferUlong@12
+VideoPortScanRom=VideoPortScanRom@16
+VideoPortSetBusData=VideoPortSetBusData@24
+VideoPortSetRegistryParameters=VideoPortSetRegistryParameters@16
+VideoPortSetTrappedEmulatorPorts=VideoPortSetTrappedEmulatorPorts@12
+;VideoPortStallExecution=HAL.KeStallExecutionProcessor
+VideoPortStallExecution=NTOSKRNL.KeStallExecutionProcessor
+VideoPortStartTimer=VideoPortStartTimer@4
+VideoPortStopTimer=VideoPortStopTimer@4
+VideoPortSynchronizeExecution=VideoPortSynchronizeExecution@16
+VideoPortUnmapMemory=VideoPortUnmapMemory@12
+VideoPortVerifyAccessRanges=VideoPortVerifyAccessRanges@12
+VideoPortWritePortUchar=VideoPortWritePortUchar@8
+VideoPortWritePortUshort=VideoPortWritePortUshort@8
+VideoPortWritePortUlong=VideoPortWritePortUlong@8
+VideoPortWritePortBufferUchar=VideoPortWritePortBufferUchar@12
+VideoPortWritePortBufferUshort=VideoPortWritePortBufferUshort@12
+VideoPortWritePortBufferUlong=VideoPortWritePortBufferUlong@12
+VideoPortWriteRegisterUchar=VideoPortWriteRegisterUchar@8
+VideoPortWriteRegisterUshort=VideoPortWriteRegisterUshort@8
+VideoPortWriteRegisterUlong=VideoPortWriteRegisterUlong@8
+VideoPortWriteRegisterBufferUchar=VideoPortWriteRegisterBufferUchar@12
+VideoPortWriteRegisterBufferUshort=VideoPortWriteRegisterBufferUshort@12
+VideoPortWriteRegisterBufferUlong=VideoPortWriteRegisterBufferUlong@12
+VideoPortZeroMemory=NTOSKRNL.RtlZeroMemory
+VideoPortZeroDeviceMemory=VideoPortZeroDeviceMemory@8
+
--- /dev/null
+
+typedef struct _VIDEOPORT_EXTENSTION_DATA
+{
+ PDEVICE_OBJECT DeviceObject;
+ PKINTERRUPT InterruptObject;
+ KSPIN_LOCK InterruptSpinLock;
+ ULONG InterruptLevel;
+ KIRQL IRQL;
+ KAFFINITY Affinity;
+ PVIDEO_HW_INITIALIZE HwInitialize;
+} VIDEOPORT_EXTENSION_DATA, *PVIDEOPORT_EXTENSION_DATA;
+
+#define MPExtensionToVPExtension(MPX) \
+ ((PVIDEOPORT_EXTENSION_DATA) ((DWORD) (MPX) - sizeof(VIDEOPORT_EXTENSION_DATA)))
+#define VPExtensionToMPExtension(VPX) \
+ ((PVOID) ((DWORD) (VPX) + sizeof(VIDEOPORT_EXTENSION_DATA)))
+
BOOLEAN AlreadyOpened = FALSE;
+VOID MouseClassPassiveCallback(PDEVICE_OBJECT ClassDeviceObject, PVOID Context)
+{
+ PDEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
+ MOUSE_INPUT_DATA PortData[MOUSE_BUFFER_SIZE];
+ ULONG InputCount;
+ KIRQL OldIrql;
+
+ assert(NULL != ClassDeviceExtension->GDIInformation.CallBack);
+ KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
+ DPRINT("Entering MouseClassPassiveCallback\n");
+ while (0 != ClassDeviceExtension->InputCount) {
+ ClassDeviceExtension->PortData -= ClassDeviceExtension->InputCount;
+ RtlMoveMemory(PortData, ClassDeviceExtension->PortData,
+ ClassDeviceExtension->InputCount * sizeof(MOUSE_INPUT_DATA));
+ InputCount = ClassDeviceExtension->InputCount;
+ ClassDeviceExtension->InputCount = 0;
+ KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
+
+ DPRINT("MouseClassPassiveCallBack() Calling GDI callback at %p\n",
+ ClassDeviceExtension->GDIInformation.CallBack);
+ /* We're jumping through hoops to get to run at PASSIVE_LEVEL, let's make
+ sure we succeeded */
+ ASSERT_IRQL(PASSIVE_LEVEL);
+ (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack)
+ (PortData, InputCount);
+
+ KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
+ }
+
+ ClassDeviceExtension->PassiveCallbackQueued = FALSE;
+ DPRINT("Leaving MouseClassPassiveCallback\n");
+ KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
+}
+
BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart,
PMOUSE_INPUT_DATA MouseDataEnd, PULONG InputCount)
{
PIRP Irp;
ULONG ReadSize;
PIO_STACK_LOCATION Stack;
+ KIRQL OldIrql;
// In classical NT, you would take the input data and pipe it through the IO system, for the GDI to read.
// In ReactOS, however, we use a GDI callback for increased mouse responsiveness. The reason we don't
// simply call from the port driver is so that our mouse class driver can support NT mouse port drivers.
+ DPRINT("Entering MouseClassCallBack\n");
/* if(ClassDeviceExtension->ReadIsPending == TRUE)
{
Irp = ClassDeviceObject->CurrentIrp;
// If we have data from the port driver and a higher service to send the data to
if((*InputCount>0) && (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL))
{
+ KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
+
if(ClassDeviceExtension->InputCount + *InputCount > MOUSE_BUFFER_SIZE)
{
ReadSize = MOUSE_BUFFER_SIZE - ClassDeviceExtension->InputCount;
ClassDeviceExtension->PortData += ReadSize;
ClassDeviceExtension->InputCount += ReadSize;
- // Throw data up to GDI callback
if(*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL) {
- DPRINT("MouseClassCallBack() Calling GDI callback at %p\n", ClassDeviceExtension->GDIInformation.CallBack);
- (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack)
- (ClassDeviceExtension->PortData - ReadSize, ReadSize);
- } else {
- DPRINT("MouseClassCallBack() NO GDI callback installed\n");
+ if (! ClassDeviceExtension->PassiveCallbackQueued) {
+ if (NULL == ClassDeviceExtension->WorkItem) {
+ ClassDeviceExtension->WorkItem = IoAllocateWorkItem(ClassDeviceObject);
}
-
- ClassDeviceExtension->PortData -= ReadSize;
- ClassDeviceExtension->InputCount -= ReadSize;
- ClassDeviceExtension->ReadIsPending = FALSE;
+ if (NULL != ClassDeviceExtension->WorkItem) {
+ DPRINT("Queueing workitem\n");
+ IoQueueWorkItem(ClassDeviceExtension->WorkItem, MouseClassPassiveCallback, DelayedWorkQueue, NULL);
+ ClassDeviceExtension->PassiveCallbackQueued = TRUE;
+ }
+ }
+ } else {
+ DPRINT("MouseClassCallBack() NO GDI callback installed\n");
+ }
+ KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
} else {
DPRINT("MouseClassCallBack() entered, InputCount = %d - DOING NOTHING\n", *InputCount);
}
+ DPRINT("Leaving MouseClassCallBack\n");
return TRUE;
}
DeviceExtension->PortData = ExAllocatePool(NonPagedPool, MOUSE_BUFFER_SIZE * sizeof(MOUSE_INPUT_DATA));
DeviceExtension->InputCount = 0;
DeviceExtension->ReadIsPending = FALSE;
+ DeviceExtension->WorkItem = NULL;
+ KeInitializeSpinLock(&(DeviceExtension->SpinLock));
+ DeviceExtension->PassiveCallbackQueued = FALSE;
// Connect our callback to the port driver
typedef struct _DEVICE_EXTENSION {
+ PIO_WORKITEM WorkItem;
+ KSPIN_LOCK SpinLock;
+ BOOLEAN PassiveCallbackQueued;
BOOLEAN ReadIsPending;
ULONG InputCount;
PMOUSE_INPUT_DATA PortData;
PRECTL DestRect, POINTL *SourcePoint,
LONG Delta, XLATEOBJ *ColorTranslation);
+VOID DIB_16BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c);
+ULONG DIB_16BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y);
+VOID DIB_16BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c);
+VOID DIB_16BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c);
+BOOL DIB_To_16BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
+ SURFGDI *DestGDI, SURFGDI *SourceGDI,
+ PRECTL DestRect, POINTL *SourcePoint,
+ LONG Delta, XLATEOBJ *ColorTranslation);
+
PFN_DIB_PutPixel DIB_24BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c);
PFN_DIB_GetPixel DIB_24BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y);
PFN_DIB_HLine DIB_24BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c);
--- /dev/null
+#undef WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdlib.h>
+#include <win32k/bitmaps.h>
+#include <win32k/debug.h>
+#include <debug.h>
+#include <ddk/winddi.h>
+#include "../eng/objects.h"
+#include "dib.h"
+
+VOID DIB_16BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c)
+{
+ PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
+ PWORD addr = (PWORD)byteaddr + x;
+
+ *addr = (WORD)c;
+}
+
+ULONG DIB_16BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y)
+{
+ PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
+ PWORD addr = (PWORD)byteaddr + x;
+
+ return (ULONG)(*addr);
+}
+
+VOID DIB_16BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
+{
+ PBYTE byteaddr = SurfObj->pvBits + y * SurfObj->lDelta;
+ PWORD addr = (PWORD)byteaddr + x1;
+ LONG cx = x1;
+
+ while(cx <= x2) {
+ *addr = (WORD)c;
+ ++addr;
+ ++cx;
+ }
+}
+
+VOID DIB_16BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
+{
+ PBYTE byteaddr = SurfObj->pvBits + y1 * SurfObj->lDelta;
+ PWORD addr = (PWORD)byteaddr + x;
+ LONG lDelta = SurfObj->lDelta;
+
+ byteaddr = (PBYTE)addr;
+ while(y1++ <= y2) {
+ *addr = (WORD)c;
+
+ byteaddr += lDelta;
+ addr = (PWORD)byteaddr;
+ }
+}
+
+BOOL DIB_To_16BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
+ SURFGDI *DestGDI, SURFGDI *SourceGDI,
+ PRECTL DestRect, POINTL *SourcePoint,
+ LONG Delta, XLATEOBJ *ColorTranslation)
+{
+ LONG i, j, sx, sy, xColor, f1;
+ PBYTE SourceBits, DestBits, SourceLine, DestLine;
+ PBYTE SourceBits_4BPP, SourceLine_4BPP;
+ DestBits = DestSurf->pvBits + (DestRect->top * DestSurf->lDelta) + 2 * DestRect->left;
+
+ switch(SourceGDI->BitsPerPixel)
+ {
+ case 1:
+ sx = SourcePoint->x;
+ sy = SourcePoint->y;
+
+ for (j=DestRect->top; j<DestRect->bottom; j++)
+ {
+ sx = SourcePoint->x;
+ for (i=DestRect->left; i<DestRect->right; i++)
+ {
+ if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
+ {
+ DIB_16BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 0));
+ } else {
+ DIB_16BPP_PutPixel(DestSurf, i, j, XLATEOBJ_iXlate(ColorTranslation, 1));
+ }
+ sx++;
+ }
+ sy++;
+ }
+ break;
+
+ case 4:
+ SourceBits_4BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
+
+ for (j=DestRect->top; j<DestRect->bottom; j++)
+ {
+ SourceLine_4BPP = SourceBits_4BPP;
+ sx = SourcePoint->x;
+ f1 = sx & 1;
+
+ for (i=DestRect->left; i<DestRect->right; i++)
+ {
+ xColor = XLATEOBJ_iXlate(ColorTranslation,
+ (*SourceLine_4BPP & altnotmask[sx&1]) >> (4 * (1-(sx & 1))));
+ DIB_16BPP_PutPixel(DestSurf, i, j, xColor);
+ if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
+ sx++;
+ }
+
+ SourceBits_4BPP += SourceSurf->lDelta;
+ }
+ break;
+
+ case 16:
+ if (NULL == ColorTranslation || 0 != (ColorTranslation->flXlate & XO_TRIVIAL))
+ {
+ SourceBits = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x;
+ for (j = DestRect->top; j < DestRect->bottom; j++)
+ {
+ RtlCopyMemory(DestBits, SourceBits, 2 * (DestRect->right - DestRect->left));
+ SourceBits += SourceSurf->lDelta;
+ DestBits += DestSurf->lDelta;
+ }
+ }
+ else
+ {
+ /* FIXME */
+ DPRINT1("DIB_16BPP_Bitblt: Unhandled ColorTranslation for 16 -> 16 copy");
+ return FALSE;
+ }
+ break;
+
+ case 24:
+ SourceLine = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + 3 * SourcePoint->x;
+ DestLine = DestBits;
+
+ for (j = DestRect->top; j < DestRect->bottom; j++)
+ {
+ SourceBits = SourceLine;
+ DestBits = DestLine;
+
+ for (i = DestRect->left; i < DestRect->right; i++)
+ {
+ xColor = (*(SourceBits + 2) << 0x10) +
+ (*(SourceBits + 1) << 0x08) +
+ (*(SourceBits));
+ *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(ColorTranslation, xColor);
+ SourceBits += 3;
+ DestBits += 2;
+ }
+
+ SourceLine += SourceSurf->lDelta;
+ DestLine += DestSurf->lDelta;
+ }
+ break;
+
+ default:
+ DbgPrint("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
+ return FALSE;
+ }
+
+ return TRUE;
+}
}
break;
+ case 16:
+ SourceBits_16BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + 2 * SourcePoint->x;
+
+ for (j=DestRect->top; j<DestRect->bottom; j++)
+ {
+ SourceLine_16BPP = SourceBits_16BPP;
+ DestLine = DestBits;
+
+ for (i=DestRect->left; i<DestRect->right; i++)
+ {
+ xColor = XLATEOBJ_iXlate(ColorTranslation, *SourceLine_16BPP);
+ *DestLine++ = xColor & 0xff;
+ *(PWORD)DestLine = xColor >> 8;
+ DestLine += 2;
+ SourceLine_16BPP++;
+ }
+
+ SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + SourceSurf->lDelta);
+ DestBits += DestSurf->lDelta;
+ }
+ break;
+
default:
DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel);
return FALSE;
#include "brush.h"
#include "clip.h"
#include "objects.h"
+#include "../dib/dib.h"
#include <include/mouse.h>
#include <include/object.h>
#include <include/dib.h>
#include <include/surface.h>
#include <include/copybits.h>
+#define NDEBUG
+#include <win32k/debug1.h>
+
BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
{
static const RECTL rclEmpty = { 0, 0, 0, 0 };
return(FALSE);
}
+static BOOL STDCALL
+BltMask(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask,
+ RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush,
+ POINTL* BrushPoint)
+{
+ LONG i, j, dx, dy, c8;
+ BYTE *tMask, *lMask;
+ PFN_DIB_PutPixel DIB_PutPixel;
+ static BYTE maskbit[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+
+ // Assign DIB functions according to bytes per pixel
+ switch(BitsPerFormat(Dest->iBitmapFormat))
+ {
+ case 1:
+ DIB_PutPixel = (PFN_DIB_PutPixel)DIB_1BPP_PutPixel;
+ break;
+
+ case 4:
+ DIB_PutPixel = (PFN_DIB_PutPixel)DIB_4BPP_PutPixel;
+ break;
+
+ case 16:
+ DIB_PutPixel = (PFN_DIB_PutPixel)DIB_16BPP_PutPixel;
+ break;
+
+ case 24:
+ DIB_PutPixel = (PFN_DIB_PutPixel)DIB_24BPP_PutPixel;
+ break;
+
+ default:
+ DbgPrint("BltMask: unsupported DIB format %u (bitsPerPixel:%u)\n", Dest->iBitmapFormat,
+ BitsPerFormat(Dest->iBitmapFormat));
+ return FALSE;
+ }
+
+ dx = DestRect->right - DestRect->left;
+ dy = DestRect->bottom - DestRect->top;
+
+ if (Mask != NULL)
+ {
+ tMask = Mask->pvBits;
+ for (j = 0; j < dy; j++)
+ {
+ lMask = tMask;
+ c8 = 0;
+ for (i = 0; i < dx; i++)
+ {
+ if (0 != (*lMask & maskbit[c8]))
+ {
+ DIB_PutPixel(Dest, DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
+ }
+ c8++;
+ if (8 == c8)
+ {
+ lMask++;
+ c8=0;
+ }
+ }
+ tMask += Mask->lDelta;
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static BOOL STDCALL
+BltPatCopy(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask,
+ RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush,
+ POINTL* BrushPoint)
+{
+ // These functions are assigned if we're working with a DIB
+ // The assigned functions depend on the bitsPerPixel of the DIB
+ PFN_DIB_HLine DIB_HLine;
+ LONG y;
+ ULONG LineWidth;
+
+ MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
+ // Assign DIB functions according to bytes per pixel
+ DPRINT("BPF: %d\n", BitsPerFormat(Dest->iBitmapFormat));
+ switch(BitsPerFormat(Dest->iBitmapFormat))
+ {
+ case 4:
+ DIB_HLine = (PFN_DIB_HLine)DIB_4BPP_HLine;
+ break;
+
+ case 16:
+ DIB_HLine = (PFN_DIB_HLine)DIB_16BPP_HLine;
+ break;
+
+ case 24:
+ DIB_HLine = (PFN_DIB_HLine)DIB_24BPP_HLine;
+ break;
+
+ default:
+ DbgPrint("BltPatCopy: unsupported DIB format %u (bitsPerPixel:%u)\n", Dest->iBitmapFormat,
+ BitsPerFormat(Dest->iBitmapFormat));
+
+ MouseSafetyOnDrawEnd(Dest, DestGDI);
+ return FALSE;
+ }
+
+ LineWidth = DestRect->right - DestRect->left;
+ for (y = DestRect->top; y < DestRect->bottom; y++)
+ {
+ DIB_HLine(Dest, DestRect->left, DestRect->right, y, Brush->iSolidColor);
+ }
+ MouseSafetyOnDrawEnd(Dest, DestGDI);
+
+ return TRUE;
+}
+
INT abs(INT nm);
BOOL STDCALL
XLATEOBJ *ColorTranslation,
RECTL *DestRect,
POINTL *SourcePoint,
- POINTL *MaskRect,
+ POINTL *MaskOrigin,
BRUSHOBJ *Brush,
POINTL *BrushOrigin,
ROP4 rop4)
// If we don't have to do anything special, we can punt to DrvCopyBits
// if it exists
- if( (Mask == NULL) && (MaskRect == NULL) && (Brush == NULL) &&
+ if( (Mask == NULL) && (MaskOrigin == NULL) && (Brush == NULL) &&
(BrushOrigin == NULL) && (rop4 == 0) )
{
canCopyBits = TRUE;
ret = DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
NULL, DestRect, &TempPoint,
- MaskRect, Brush, BrushOrigin, rop4);
+ MaskOrigin, Brush, BrushOrigin, rop4);
MouseSafetyOnDrawEnd(Source, SourceGDI);
MouseSafetyOnDrawEnd(Dest, DestGDI);
/* The code currently assumes there will be a source bitmap. This is not true when, for example, using this function to
* paint a brush pattern on the destination. */
- if(!Source)
+ if(!Source && 0xaacc != rop4 && PATCOPY != rop4)
{
DbgPrint("EngBitBlt: A source is currently required, even though not all operations require one (FIXME)\n");
return FALSE;
}
// * The source bitmap is not managed by the GDI and we didn't already obtain it using EngCopyBits from the device
- if(Source->iType != STYPE_BITMAP && SourceGDI->CopyBits == NULL)
+ if(NULL != Source && STYPE_BITMAP != Source->iType && NULL == SourceGDI->CopyBits)
{
if (SourceGDI->BitBlt!=NULL)
{
// Request the device driver to return the bitmap in a format compatible with the device
ret = SourceGDI->BitBlt(Dest, Source, Mask, ClipRegion,
NULL, DestRect, SourcePoint,
- MaskRect, Brush, BrushOrigin, rop4);
+ MaskOrigin, Brush, BrushOrigin, rop4);
MouseSafetyOnDrawEnd(Source, SourceGDI);
MouseSafetyOnDrawEnd(Dest, DestGDI);
clippingType = ClipRegion->iDComplexity;
}
+ if (0xaacc == rop4)
+ {
+ return BltMask(Dest, DestGDI, Mask, DestRect, MaskOrigin, Brush, BrushOrigin);
+ } else if (PATCOPY == rop4) {
+ return BltPatCopy(Dest, DestGDI, Mask, DestRect, MaskOrigin, Brush, BrushOrigin);
+ }
+
+
// We don't handle color translation just yet [we dont have to.. REMOVE REMOVE REMOVE]
switch(clippingType)
{
#include "clip.h"
#include <include/object.h>
+#define NDEBUG
#include <win32k/debug1.h>
VOID IntEngDeleteClipRegion(CLIPOBJ *ClipObj)
PENUMRECTS pERects = (PENUMRECTS)EnumRects;
//calculate how many rectangles we should copy
- nCopy = MIN( ClipGDI->EnumMax-ClipGDI->EnumPos,
- MIN( ClipGDI->EnumRects.c, (ObjSize-sizeof(ULONG))/sizeof(RECTL)));
+ nCopy = MIN( ClipGDI->EnumMax - ClipGDI->EnumPos,
+ MIN( ClipGDI->EnumRects.c - ClipGDI->EnumPos,
+ (ObjSize - sizeof(ULONG)) / sizeof(RECTL)));
- RtlCopyMemory( &(pERects->arcl), &(ClipGDI->EnumRects.arcl), nCopy*sizeof(RECTL) );
+ RtlCopyMemory( pERects->arcl, ClipGDI->EnumRects.arcl + ClipGDI->EnumPos,
+ nCopy * sizeof(RECTL) );
pERects->c = nCopy;
ClipGDI->EnumPos+=nCopy;
- if(ClipGDI->EnumPos > ClipGDI->EnumRects.c)
- return FALSE;
- else
- return TRUE;
+ return ClipGDI->EnumPos < ClipGDI->EnumRects.c;
}
DestRect, SourcePoint, Delta, ColorTranslation);
break;
+ case 16:
+ return DIB_To_16BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
+ DestRect, SourcePoint, Delta, ColorTranslation);
+ break;
+
case 24:
return DIB_To_24BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI,
DestRect, SourcePoint, Delta, ColorTranslation);
#include <ddk/winddi.h>
+#include <include/inteng.h>
#include "objects.h"
#include "../dib/dib.h"
RECTL *RectBounds,
MIX mix)
{
- BOOLEAN ret;
- SURFGDI *SurfGDI;
- LONG x, y, d, deltax, deltay, i, length, xchange, ychange, error, hx, vy;
+ LONG x, y, deltax, deltay, i, length, xchange, ychange, error, hx, vy;
+ ULONG Pixel = Brush->iSolidColor;
// These functions are assigned if we're working with a DIB
// The assigned functions depend on the bitsPerPixel of the DIB
PFN_DIB_HLine DIB_HLine;
PFN_DIB_VLine DIB_VLine;
- SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface);
-
- MouseSafetyOnDrawStart(Surface, SurfGDI, x1, y1, x2, y2);
-
- if(Surface->iType!=STYPE_BITMAP)
- {
- // Call the driver's DrvLineTo
- ret = SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
- MouseSafetyOnDrawEnd(Surface, SurfGDI);
- return ret;
- }
-
// Assign DIB functions according to bytes per pixel
switch(BitsPerFormat(Surface->iBitmapFormat))
{
DIB_VLine = (PFN_DIB_VLine)DIB_4BPP_VLine;
break;
+ case 16:
+ DIB_PutPixel = (PFN_DIB_PutPixel)DIB_16BPP_PutPixel;
+ DIB_HLine = (PFN_DIB_HLine)DIB_16BPP_HLine;
+ DIB_VLine = (PFN_DIB_VLine)DIB_16BPP_VLine;
+ break;
+
case 24:
DIB_PutPixel = (PFN_DIB_PutPixel)DIB_24BPP_PutPixel;
DIB_HLine = (PFN_DIB_HLine)DIB_24BPP_HLine;
default:
DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
BitsPerFormat(Surface->iBitmapFormat));
-
- MouseSafetyOnDrawEnd(Surface, SurfGDI);
return FALSE;
}
vy = y1;
}
- if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; }
- if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Brush->iSolidColor); MouseSafetyOnDrawEnd(Surface, SurfGDI); return TRUE; }
+ if(y1==y2) { DIB_HLine(Surface, hx, hx + deltax, y1, Pixel); return TRUE; }
+ if(x1==x2) { DIB_VLine(Surface, x1, vy, vy + deltay, Pixel); return TRUE; }
error=0;
i=0;
length=deltay+1;
while(i<length)
{
- DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
+ DIB_PutPixel(Surface, x, y, Pixel);
y=y+ychange;
error=error+deltax;
length=deltax+1;
while(i<length)
{
- DIB_PutPixel(Surface, x, y, Brush->iSolidColor);
+ DIB_PutPixel(Surface, x, y, Pixel);
x=x+xchange;
error=error+deltay;
if(error>deltax)
}
}
+ return TRUE;
+}
+
+BOOL STDCALL
+IntEngLineTo(SURFOBJ *Surface,
+ CLIPOBJ *Clip,
+ BRUSHOBJ *Brush,
+ LONG x1,
+ LONG y1,
+ LONG x2,
+ LONG y2,
+ RECTL *RectBounds,
+ MIX mix)
+{
+ BOOLEAN ret;
+ SURFGDI *SurfGDI;
+
+ /* No success yet */
+ ret = FALSE;
+ SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface);
+
+ MouseSafetyOnDrawStart(Surface, SurfGDI, x1, y1, x2, y2);
+
+ if (NULL != SurfGDI->LineTo) {
+ /* Call the driver's DrvLineTo */
+ ret = SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
+ }
+
+#if 0
+ if (! ret && NULL != SurfGDI->StrokePath) {
+ /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */
+ }
+#endif
+
+ if (! ret) {
+ ret = EngLineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
+ }
+
MouseSafetyOnDrawEnd(Surface, SurfGDI);
- return TRUE;
+ return ret;
}
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: mouse.c,v 1.16 2003/01/24 23:25:34 ei Exp $
+/* $Id: mouse.c,v 1.17 2003/02/15 19:16:33 gvg Exp $
*
* PROJECT: ReactOS kernel
* PURPOSE: Mouse
#include "objects.h"
#include "include/msgqueue.h"
+#define NDEBUG
+#include <debug.h>
+
/* GLOBALS *******************************************************************/
static BOOLEAN SafetySwitch = FALSE;
RECTL MouseRect;
LONG tmp;
+ /* Mouse is not allowed to move if GDI is busy drawing */
+ SafetySwitch2 = TRUE;
+
if (SurfObj == NULL)
{
return(FALSE);
if (((mouse_x + mouse_width) >= HazardX1) && (mouse_x <= HazardX2) &&
((mouse_y + mouse_height) >= HazardY1) && (mouse_y <= HazardY2))
{
- SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect);
SafetySwitch = TRUE;
+ SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect);
}
- /* Mouse is not allowed to move if GDI is busy drawing */
- SafetySwitch2 = TRUE;
-
return(TRUE);
}
typedef VOID STDCALL (*PFN_MovePointer)(PSURFOBJ, LONG, LONG, PRECTL);
-typedef VOID STDCALL (*PFN_SetPointerShape)(PSURFOBJ, PSURFOBJ, PSURFOBJ, PXLATEOBJ,
+typedef ULONG STDCALL (*PFN_SetPointerShape)(PSURFOBJ, PSURFOBJ, PSURFOBJ, PXLATEOBJ,
LONG, LONG, LONG, LONG, PRECTL, ULONG);
typedef HBITMAP STDCALL (*PFN_CreateDeviceBitmap)(DHPDEV, SIZEL, ULONG);
HPALETTE SourcePal;
ULONG *translationTable;
+
+ ULONG RedMask;
+ ULONG GreenMask;
+ ULONG BlueMask;
+ INT RedShift;
+ INT GreenShift;
+ INT BlueShift;
+ BOOL UseShiftAndMask;
} XLATEGDI;
// List of GDI objects
#include "brush.h"
#include "clip.h"
-//#define NDEBUG
+#define NDEBUG
#include <win32k/debug1.h>
BOOL FillSolid(SURFOBJ *Surface, PRECTL pRect, ULONG iColor)
DIB_VLine = (PFN_DIB_VLine)DIB_4BPP_VLine;
break;
+ case 16:
+ DIB_PutPixel = (PFN_DIB_PutPixel)DIB_16BPP_PutPixel;
+ DIB_HLine = (PFN_DIB_HLine)DIB_16BPP_HLine;
+ DIB_VLine = (PFN_DIB_VLine)DIB_16BPP_VLine;
+ break;
+
case 24:
DIB_PutPixel = (PFN_DIB_PutPixel)DIB_24BPP_PutPixel;
DIB_HLine = (PFN_DIB_HLine)DIB_24BPP_HLine;
break;
default:
- DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
+ DbgPrint("FillSolid: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
BitsPerFormat(Surface->iBitmapFormat));
MouseSafetyOnDrawEnd(Surface, SurfaceGDI);
{
RECT_ENUM RectEnum;
BOOL EnumMore;
+ ULONG i;
DPRINT("ClipRegion->iMode:%d, ClipRegion->iDComplexity: %d\n Color: %d", ClipRegion->iMode, ClipRegion->iDComplexity, iColor);
switch(ClipRegion->iMode) {
do {
EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum);
- FillSolid(Surface, &RectEnum.arcl[0], iColor);
+ for (i = 0; i < RectEnum.c; i++) {
+ FillSolid(Surface, RectEnum.arcl + i, iColor);
+ }
} while (EnumMore);
}
#include <include/paint.h>
#include "handle.h"
-//#define NDEBUG
+#define NDEBUG
#include <win32k/debug1.h>
INT BitsPerFormat(ULONG Format)
// FIXME: Call GDI_LockObject (see subsys/win32k/objects/gdi.c)
return (SURFOBJ*)AccessUserObject((ULONG)Surface);
}
+
+VOID STDCALL
+EngUnlockSurface(IN SURFOBJ *Surface)
+{
+ // FIXME: Call GDI_UnlockObject
+}
#include <include/object.h>
#include "handle.h"
-//#define NDEBUG
+#define NDEBUG
#include <win32k/debug1.h>
ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0;
}
}
+static VOID BitMasksFromPal(USHORT PalType, PPALGDI Palette,
+ PULONG RedMask, PULONG BlueMask, PULONG GreenMask)
+{
+ switch(PalType)
+ {
+ case PAL_RGB:
+ *RedMask = RGB(255, 0, 0);
+ *GreenMask = RGB(0, 255, 0);
+ *BlueMask = RGB(0, 0, 255);
+ break;
+ case PAL_BGR:
+ *RedMask = RGB(0, 0, 255);
+ *GreenMask = RGB(0, 255, 0);
+ *BlueMask = RGB(255, 0, 0);
+ break;
+ case PAL_BITFIELDS:
+ *RedMask = Palette->RedMask;
+ *BlueMask = Palette->BlueMask;
+ *GreenMask = Palette->GreenMask;
+ break;
+ }
+}
+
+/*
+ * Calculate the number of bits Mask must be shift to the left to get a
+ * 1 in the most significant bit position
+ */
+static INT CalculateShift(ULONG Mask)
+{
+ INT Shift = 0;
+ ULONG LeftmostBit = 1 << (8 * sizeof(ULONG) - 1);
+
+ while (0 == (Mask & LeftmostBit) && Shift < 8 * sizeof(ULONG))
+ {
+ Mask = Mask << 1;
+ Shift++;
+ }
+
+ return Shift;
+}
+
+static ULONG ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color)
+{
+ ULONG TranslatedColor;
+
+ TranslatedColor = 0;
+ if (XlateGDI->RedShift < 0)
+ {
+ TranslatedColor = (Color >> -(XlateGDI->RedShift)) & XlateGDI->RedMask;
+ } else
+ TranslatedColor = (Color << XlateGDI->RedShift) & XlateGDI->RedMask;
+ if (XlateGDI->GreenShift < 0)
+ {
+ TranslatedColor |= (Color >> -(XlateGDI->GreenShift)) & XlateGDI->GreenMask;
+ } else
+ TranslatedColor |= (Color << XlateGDI->GreenShift) & XlateGDI->GreenMask;
+ if (XlateGDI->BlueShift < 0)
+ {
+ TranslatedColor |= (Color >> -(XlateGDI->BlueShift)) & XlateGDI->BlueMask;
+ } else
+ TranslatedColor |= (Color << XlateGDI->BlueShift) & XlateGDI->BlueMask;
+
+ return TranslatedColor;
+}
+
XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
HPALETTE PaletteDest, HPALETTE PaletteSource)
{
XLATEGDI *XlateGDI;
PALGDI *SourcePalGDI, *DestPalGDI;
ULONG IndexedColors;
+ ULONG SourceRedMask, SourceGreenMask, SourceBlueMask;
+ ULONG DestRedMask, DestGreenMask, DestBlueMask;
+ UINT i;
NewXlate = (HPALETTE)CreateGDIHandle(sizeof( XLATEGDI ), sizeof( XLATEOBJ ));
if( !ValidEngHandle( NewXlate ) )
return NULL;
- XlateObj = (XLATEOBJ*) AccessUserObject( NewXlate );
- XlateGDI = (XLATEGDI*) AccessInternalObject( NewXlate );
+ XlateObj = (XLATEOBJ*) AccessUserObject( (ULONG) NewXlate );
+ XlateGDI = (XLATEGDI*) AccessInternalObject( (ULONG) NewXlate );
ASSERT( XlateObj );
ASSERT( XlateGDI );
- if(SourcePalType == PAL_INDEXED)
- SourcePalGDI = (PALGDI*)AccessInternalObject((ULONG)PaletteSource);
- if(DestPalType == PAL_INDEXED)
- DestPalGDI = (PALGDI*)AccessInternalObject((ULONG)PaletteDest);
+ SourcePalGDI = (PALGDI*)AccessInternalObject((ULONG)PaletteSource);
+ DestPalGDI = (PALGDI*)AccessInternalObject((ULONG)PaletteDest);
XlateObj->iSrcType = SourcePalType;
XlateObj->iDstType = DestPalType;
XlateObj->flXlate = 0;
+ XlateGDI->UseShiftAndMask = FALSE;
+
+ /* Compute bit fiddeling constants unless both palettes are indexed, then we don't need them */
+ if (PAL_INDEXED != SourcePalType || PAL_INDEXED != DestPalType)
+ {
+ BitMasksFromPal(PAL_INDEXED == SourcePalType ? PAL_RGB : SourcePalType,
+ SourcePalGDI, &SourceRedMask, &SourceBlueMask, &SourceGreenMask);
+ BitMasksFromPal(PAL_INDEXED == DestPalType ? PAL_RGB : DestPalType,
+ DestPalGDI, &DestRedMask, &DestBlueMask, &DestGreenMask);
+ XlateGDI->RedShift = CalculateShift(SourceRedMask) - CalculateShift(DestRedMask);
+ XlateGDI->RedMask = DestRedMask;
+ XlateGDI->GreenShift = CalculateShift(SourceGreenMask) - CalculateShift(DestGreenMask);
+ XlateGDI->GreenMask = DestGreenMask;
+ XlateGDI->BlueShift = CalculateShift(SourceBlueMask) - CalculateShift(DestBlueMask);
+ XlateGDI->BlueMask = DestBlueMask;
+ }
+
// If source and destination palettes are the same or if they're RGB/BGR
if( (PaletteDest == PaletteSource) ||
((DestPalType == PAL_RGB) && (SourcePalType == PAL_RGB)) ||
return XlateObj;
}
+ /* If source and destination are bitfield based (RGB and BGR are just special bitfields) */
+ if ((PAL_RGB == DestPalType || PAL_BGR == DestPalType || PAL_BITFIELDS == DestPalType) &&
+ (PAL_RGB == SourcePalType || PAL_BGR == SourcePalType || PAL_BITFIELDS == SourcePalType))
+ {
+ if (SourceRedMask == DestRedMask &&
+ SourceBlueMask == DestBlueMask &&
+ SourceGreenMask == DestGreenMask)
+ {
+ XlateObj->flXlate |= XO_TRIVIAL;
+ }
+ XlateGDI->UseShiftAndMask = TRUE;
+ return XlateObj;
+ }
+
// Prepare the translation table
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
{
// Converting from indexed to indexed
IndexedToIndexedTranslationTable(XlateGDI->translationTable, DestPalGDI, SourcePalGDI);
} else
- if(XlateObj->iDstType == PAL_RGB)
+ if (PAL_RGB == XlateObj->iDstType || PAL_BITFIELDS == XlateObj->iDstType )
{
// FIXME: Is this necessary? I think the driver has to call this
// function anyways if pulXlate is NULL and Source is PAL_INDEXED
XLATEOBJ_cGetPalette(XlateObj, XO_SRCPALETTE,
SourcePalGDI->NumColors,
XlateGDI->translationTable);
+ if (PAL_BITFIELDS == XlateObj->iDstType)
+ {
+ for (i = 0; i < SourcePalGDI->NumColors; i++)
+ {
+ XlateGDI->translationTable[i] = ShiftAndMask(XlateGDI, XlateGDI->translationTable[i]);
+ }
+ }
}
XlateObj->pulXlate = XlateGDI->translationTable;
{
return Color;
} else
+ if(XlateGDI->UseShiftAndMask)
+ {
+ return ShiftAndMask(XlateGDI, Color);
+ } else
if(XlateObj->iSrcType == PAL_RGB)
{
// FIXME: should we cache colors used often?
--- /dev/null
+#ifndef __WIN32K_INTENG_H
+#define __WIN32K_INTENG_H
+
+/* Definitions of IntEngXxx functions */
+
+extern BOOL STDCALL IntEngLineTo(SURFOBJ *Surface,
+ CLIPOBJ *Clip,
+ BRUSHOBJ *Brush,
+ LONG x1,
+ LONG y1,
+ LONG x2,
+ LONG y2,
+ RECTL *RectBounds,
+ MIX mix);
+
+#endif
-# $Id: makefile,v 1.54 2002/11/24 20:18:35 jfilby Exp $
+# $Id: makefile,v 1.55 2003/02/15 19:16:33 gvg Exp $
PATH_TO_TOP = ../..
objects/region.o objects/text.o objects/wingl.o \
objects/bezier.o objects/objconv.o objects/dib.o \
objects/palette.o objects/rect.o
-DIB_OBJECTS = dib/dib1bpp.o dib/dib4bpp.o dib/dib24bpp.o
+DIB_OBJECTS = dib/dib1bpp.o dib/dib4bpp.o dib/dib16bpp.o dib/dib24bpp.o
FREETYPE_OBJECTS = freetype/ctype.o freetype/grfont.o \
freetype/src/base/ftsystem.o freetype/src/base/ftdebug.o \
freetype/src/base/ftinit.o freetype/src/base/ftbase.o \
-/* $Id: dc.c,v 1.45 2003/01/25 23:09:40 ei Exp $
+/* $Id: dc.c,v 1.46 2003/02/15 19:16:34 gvg Exp $
*
* DC.C - Device context functions
*
#include <win32k/text.h>
#include "../eng/handle.h"
-//#define NDEBUG
+#define NDEBUG
#include <win32k/debug1.h>
static GDIDEVICE PrimarySurface;
LPCWSTR Output,
CONST PDEVMODEW InitData)
{
- HDC hNewDC;
- PDC NewDC;
- HDC hDC = NULL;
+ HDC hNewDC;
+ PDC NewDC;
+ HDC hDC = NULL;
+ PSURFOBJ SurfObj;
+ PSURFGDI SurfGDI;
/* Check for existing DC object */
if ((hNewDC = DC_FindOpenDC(Driver)) != NULL)
/* FIXME: get mode selection information from somewhere */
NewDC->DMW.dmLogPixels = 96;
- NewDC->DMW.dmBitsPerPel = 4;
- NewDC->DMW.dmPelsWidth = 640;
- NewDC->DMW.dmPelsHeight = 480;
+ SurfGDI = (PSURFGDI)AccessInternalObject(PrimarySurface.Handle);
+ NewDC->DMW.dmBitsPerPel = SurfGDI->BitsPerPixel;
+ NewDC->DMW.dmPelsWidth = SurfGDI->SurfObj.sizlBitmap.cx;
+ NewDC->DMW.dmPelsHeight = SurfGDI->SurfObj.sizlBitmap.cy;
NewDC->DMW.dmDisplayFlags = 0;
NewDC->DMW.dmDisplayFrequency = 0;
- NewDC->w.bitsPerPixel = 4; // FIXME: set this here??
+ NewDC->w.bitsPerPixel = SurfGDI->BitsPerPixel; // FIXME: set this here??
NewDC->w.hPalette = NewDC->DevInfo.hpalDefault;
#include <win32k/dc.h>
#include <win32k/pen.h>
#include <include/object.h>
+#include <include/inteng.h>
-// #define NDEBUG
+#define NDEBUG
#include <win32k/debug1.h>
BOOL
TopRect += dc->w.DCOrgY;
BottomRect += dc->w.DCOrgY;
- ret = EngLineTo(SurfObj,
- NULL, // ClipObj,
- BrushObj,
- LeftRect, TopRect, RightRect, TopRect,
- RectBounds, // Bounding rectangle
- dc->w.ROPmode); // MIX
-
- ret = EngLineTo(SurfObj,
- NULL, // ClipObj,
- BrushObj,
- RightRect, TopRect, RightRect, BottomRect,
- RectBounds, // Bounding rectangle
- dc->w.ROPmode); // MIX
-
- ret = EngLineTo(SurfObj,
- NULL, // ClipObj,
- BrushObj,
- LeftRect, BottomRect, RightRect, BottomRect,
- RectBounds, // Bounding rectangle
- dc->w.ROPmode); // MIX
-
- ret = EngLineTo(SurfObj,
- NULL, // ClipObj,
- BrushObj,
- LeftRect, TopRect, LeftRect, BottomRect,
- RectBounds, // Bounding rectangle
- dc->w.ROPmode); // MIX */
+ ret = IntEngLineTo(SurfObj,
+ NULL, // ClipObj,
+ BrushObj,
+ LeftRect, TopRect, RightRect, TopRect,
+ RectBounds, // Bounding rectangle
+ dc->w.ROPmode); // MIX
+
+ ret = IntEngLineTo(SurfObj,
+ NULL, // ClipObj,
+ BrushObj,
+ RightRect, TopRect, RightRect, BottomRect,
+ RectBounds, // Bounding rectangle
+ dc->w.ROPmode); // MIX
+
+ ret = IntEngLineTo(SurfObj,
+ NULL, // ClipObj,
+ BrushObj,
+ LeftRect, BottomRect, RightRect, BottomRect,
+ RectBounds, // Bounding rectangle
+ dc->w.ROPmode); // MIX
+
+ ret = IntEngLineTo(SurfObj,
+ NULL, // ClipObj,
+ BrushObj,
+ LeftRect, TopRect, LeftRect, BottomRect,
+ RectBounds, // Bounding rectangle
+ dc->w.ROPmode); // MIX */
// FIXME: BrushObj is obtained above; decide which one is correct
BrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
#include <win32k/path.h>
#include <win32k/pen.h>
#include <win32k/region.h>
+#include <include/inteng.h>
-// #define NDEBUG
+#define NDEBUG
#include <win32k/debug1.h>
+
BOOL
STDCALL
W32kAngleArc(HDC hDC,
BOOL ret;
PPENOBJ pen;
PROSRGNDATA reg;
+#ifndef TODO
+ RECT defaultrect;
+#endif
if(!dc) return FALSE;
ASSERT( pen );
// not yet implemented ASSERT( reg );
+#ifndef TODO
+ if (NULL == reg) {
+ defaultrect.left = 0;
+ defaultrect.top = 0;
+ defaultrect.right = 640;
+ defaultrect.bottom = 480;
+
+ reg = &defaultrect;
+ }
+#endif
/* Draw the line according to the DC origin */
- ret = EngLineTo(SurfObj,
- NULL, // ClipObj
- PenToBrushObj(dc, pen),
- dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY,
- dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd,
- reg, // Bounding rectangle
- dc->w.ROPmode); // MIX
-
- GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC );
- GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC);
+ ret = IntEngLineTo(SurfObj,
+ NULL, // ClipObj
+ PenToBrushObj(dc, pen),
+ dc->w.DCOrgX + dc->w.CursPosX, dc->w.DCOrgY + dc->w.CursPosY,
+ dc->w.DCOrgX + XEnd, dc->w.DCOrgY + YEnd,
+ reg, // Bounding rectangle
+ dc->w.ROPmode); // MIX
+
+ GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC );
+ GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC);
}
if(ret) {
dc->w.CursPosX = XEnd;
STUB(EngUnicodeToMultiByteN)
STUB(EngUnloadImage)
STUB(EngUnlockDriverObj)
-STUB(EngUnlockSurface)
STUB(EngUnmapEvent)
STUB(EngUnmapFontFile)
STUB(EngUnsecureMem)
-; $Id: win32k.def,v 1.14 2002/10/28 15:03:18 robd Exp $
+; $Id: win32k.def,v 1.15 2003/02/15 19:16:33 gvg Exp $
;
; win32k.def
;
EngMapModule
EngMarkBandingSurface
EngMovePointer
-EngMulDiv
+EngMulDiv@12
EngMultiByteToUnicodeN
EngMultiByteToWideChar
EngPaint@20
EngUnicodeToMultiByteN
EngUnloadImage
EngUnlockDriverObj
-EngUnlockSurface
+EngUnlockSurface@4
EngUnmapEvent
EngUnmapFontFile
; EngUnsecureMem = NTOSKRNL.MmUnsecureVirtualMemory
-; $Id: win32k.edf,v 1.7 2002/10/28 15:03:18 robd Exp $
+; $Id: win32k.edf,v 1.8 2003/02/15 19:16:33 gvg Exp $
;
; win32k.def
;
EngMapModule
EngMarkBandingSurface
EngMovePointer
-EngMulDiv
+EngMulDiv=EngMulDiv@12
EngMultiByteToUnicodeN
EngMultiByteToWideChar
EngPaint=EngPaint@20
EngUnicodeToMultiByteN
EngUnloadImage
EngUnlockDriverObj
-EngUnlockSurface
+EngUnlockSurface=EngUnlockSurface@4
EngUnmapEvent
EngUnmapFontFile
; EngUnsecureMem = NTOSKRNL.MmUnsecureVirtualMemory