Support for VMware video drivers

svn path=/trunk/; revision=4151
This commit is contained in:
Gé van Geldorp 2003-02-15 19:16:34 +00:00
parent d9dc30e0aa
commit aaa7b9a682
28 changed files with 1793 additions and 119 deletions

View file

@ -1,4 +1,4 @@
# $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 = ../../../..
@ -6,7 +6,7 @@ TARGET_TYPE = driver
TARGET_NAME = vgamp
TARGET_DDKLIBS = vidport.a
TARGET_DDKLIBS = videoprt.a
TARGET_OBJECTS = \
initvga.o \

View file

@ -0,0 +1,4 @@
vidport.coff
*.o
*.sym
*.sys

View file

@ -0,0 +1,965 @@
/* $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;
}

View file

@ -0,0 +1,60 @@
; $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

View file

@ -0,0 +1,61 @@
; $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

View file

@ -0,0 +1,17 @@
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)))

View file

@ -20,6 +20,40 @@
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)
{
@ -27,11 +61,13 @@ BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA M
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;
@ -56,6 +92,8 @@ BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA M
// 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;
@ -74,22 +112,26 @@ BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA M
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;
}
@ -122,6 +164,9 @@ NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT ClassDeviceObject)
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

View file

@ -1,4 +1,7 @@
typedef struct _DEVICE_EXTENSION {
PIO_WORKITEM WorkItem;
KSPIN_LOCK SpinLock;
BOOLEAN PassiveCallbackQueued;
BOOLEAN ReadIsPending;
ULONG InputCount;
PMOUSE_INPUT_DATA PortData;

View file

@ -25,6 +25,15 @@ BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
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);

View file

@ -0,0 +1,159 @@
#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;
}

View file

@ -146,6 +146,28 @@ BOOLEAN DIB_To_24BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
}
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;

View file

@ -14,12 +14,16 @@
#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 };
@ -40,6 +44,120 @@ BOOL EngIntersectRect(PRECTL prcDst, PRECTL prcSrc1, PRECTL prcSrc2)
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
@ -50,7 +168,7 @@ EngBitBlt(SURFOBJ *Dest,
XLATEOBJ *ColorTranslation,
RECTL *DestRect,
POINTL *SourcePoint,
POINTL *MaskRect,
POINTL *MaskOrigin,
BRUSHOBJ *Brush,
POINTL *BrushOrigin,
ROP4 rop4)
@ -82,7 +200,7 @@ EngBitBlt(SURFOBJ *Dest,
// 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;
@ -119,7 +237,7 @@ EngBitBlt(SURFOBJ *Dest,
ret = DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
NULL, DestRect, &TempPoint,
MaskRect, Brush, BrushOrigin, rop4);
MaskOrigin, Brush, BrushOrigin, rop4);
MouseSafetyOnDrawEnd(Source, SourceGDI);
MouseSafetyOnDrawEnd(Dest, DestGDI);
@ -130,21 +248,21 @@ EngBitBlt(SURFOBJ *Dest,
/* 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);
@ -163,6 +281,14 @@ EngBitBlt(SURFOBJ *Dest,
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)
{

View file

@ -14,6 +14,7 @@
#include "clip.h"
#include <include/object.h>
#define NDEBUG
#include <win32k/debug1.h>
VOID IntEngDeleteClipRegion(CLIPOBJ *ClipObj)
@ -120,16 +121,15 @@ CLIPOBJ_bEnum(IN PCLIPOBJ 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;
}

View file

@ -44,6 +44,11 @@ BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
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);

View file

@ -1,4 +1,5 @@
#include <ddk/winddi.h>
#include <include/inteng.h>
#include "objects.h"
#include "../dib/dib.h"
@ -17,9 +18,8 @@ EngLineTo(SURFOBJ *Surface,
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
@ -27,18 +27,6 @@ EngLineTo(SURFOBJ *Surface,
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))
{
@ -54,6 +42,12 @@ EngLineTo(SURFOBJ *Surface,
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;
@ -63,8 +57,6 @@ EngLineTo(SURFOBJ *Surface,
default:
DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat,
BitsPerFormat(Surface->iBitmapFormat));
MouseSafetyOnDrawEnd(Surface, SurfGDI);
return FALSE;
}
@ -96,8 +88,8 @@ EngLineTo(SURFOBJ *Surface,
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;
@ -107,7 +99,7 @@ EngLineTo(SURFOBJ *Surface,
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;
@ -123,7 +115,7 @@ EngLineTo(SURFOBJ *Surface,
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)
@ -135,7 +127,45 @@ EngLineTo(SURFOBJ *Surface,
}
}
MouseSafetyOnDrawEnd(Surface, SurfGDI);
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 ret;
}

View file

@ -16,7 +16,7 @@
* 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
@ -34,6 +34,9 @@
#include "objects.h"
#include "include/msgqueue.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
static BOOLEAN SafetySwitch = FALSE;
@ -122,6 +125,9 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1,
RECTL MouseRect;
LONG tmp;
/* Mouse is not allowed to move if GDI is busy drawing */
SafetySwitch2 = TRUE;
if (SurfObj == NULL)
{
return(FALSE);
@ -144,13 +150,10 @@ MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1,
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);
}

View file

@ -131,7 +131,7 @@ typedef VOID STDCALL (*PFN_Synchronize)(DHPDEV, PRECTL);
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);
@ -174,6 +174,14 @@ typedef struct _XLATEGDI {
HPALETTE SourcePal;
ULONG *translationTable;
ULONG RedMask;
ULONG GreenMask;
ULONG BlueMask;
INT RedShift;
INT GreenShift;
INT BlueShift;
BOOL UseShiftAndMask;
} XLATEGDI;
// List of GDI objects

View file

@ -20,7 +20,7 @@
#include "brush.h"
#include "clip.h"
//#define NDEBUG
#define NDEBUG
#include <win32k/debug1.h>
BOOL FillSolid(SURFOBJ *Surface, PRECTL pRect, ULONG iColor)
@ -55,6 +55,12 @@ 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;
@ -62,7 +68,7 @@ BOOL FillSolid(SURFOBJ *Surface, PRECTL pRect, ULONG iColor)
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);
@ -86,6 +92,7 @@ BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
{
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) {
@ -106,7 +113,9 @@ BOOL EngPaintRgn(SURFOBJ *Surface, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix,
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);
}

View file

@ -19,7 +19,7 @@
#include <include/paint.h>
#include "handle.h"
//#define NDEBUG
#define NDEBUG
#include <win32k/debug1.h>
INT BitsPerFormat(ULONG Format)
@ -243,3 +243,9 @@ EngLockSurface(IN HSURF Surface)
// 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
}

View file

@ -17,7 +17,7 @@
#include <include/object.h>
#include "handle.h"
//#define NDEBUG
#define NDEBUG
#include <win32k/debug1.h>
ULONG CCMLastSourceColor = 0, CCMLastColorMatch = 0;
@ -91,6 +91,71 @@ VOID IndexedToIndexedTranslationTable(ULONG *TranslationTable,
}
}
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)
{
@ -101,20 +166,21 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
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;
@ -125,6 +191,23 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
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)) ||
@ -134,6 +217,20 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
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) )
{
@ -160,7 +257,7 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
// 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
@ -170,6 +267,13 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
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;
@ -232,6 +336,10 @@ XLATEOBJ_iXlate(XLATEOBJ *XlateObj,
{
return Color;
} else
if(XlateGDI->UseShiftAndMask)
{
return ShiftAndMask(XlateGDI, Color);
} else
if(XlateObj->iSrcType == PAL_RGB)
{
// FIXME: should we cache colors used often?

View file

@ -0,0 +1,16 @@
#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

View file

@ -1,4 +1,4 @@
# $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 = ../..
@ -40,7 +40,7 @@ OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \
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 \

View file

@ -1,4 +1,4 @@
/* $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
*
@ -20,7 +20,7 @@
#include <win32k/text.h>
#include "../eng/handle.h"
//#define NDEBUG
#define NDEBUG
#include <win32k/debug1.h>
static GDIDEVICE PrimarySurface;
@ -276,9 +276,11 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
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)
@ -323,13 +325,14 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
/* 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;

View file

@ -6,8 +6,9 @@
#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
@ -106,33 +107,33 @@ W32kRectangle(HDC hDC,
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 = IntEngLineTo(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 = IntEngLineTo(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 = IntEngLineTo(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, 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);

View file

@ -8,10 +8,12 @@
#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,
@ -109,6 +111,9 @@ W32kLineTo(HDC hDC,
BOOL ret;
PPENOBJ pen;
PROSRGNDATA reg;
#ifndef TODO
RECT defaultrect;
#endif
if(!dc) return FALSE;
@ -120,18 +125,28 @@ W32kLineTo(HDC hDC,
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
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);
GDIOBJ_UnlockObj( dc->w.hGCClipRgn, GO_REGION_MAGIC );
GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC);
}
if(ret) {
dc->w.CursPosX = XEnd;

View file

@ -71,7 +71,6 @@ STUB(EngTextOut)
STUB(EngUnicodeToMultiByteN)
STUB(EngUnloadImage)
STUB(EngUnlockDriverObj)
STUB(EngUnlockSurface)
STUB(EngUnmapEvent)
STUB(EngUnmapFontFile)
STUB(EngUnsecureMem)

View file

@ -1,4 +1,4 @@
; $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
;
@ -72,7 +72,7 @@ EngMapFontFile
EngMapModule
EngMarkBandingSurface
EngMovePointer
EngMulDiv
EngMulDiv@12
EngMultiByteToUnicodeN
EngMultiByteToWideChar
EngPaint@20
@ -101,7 +101,7 @@ EngTransparentBlt@32
EngUnicodeToMultiByteN
EngUnloadImage
EngUnlockDriverObj
EngUnlockSurface
EngUnlockSurface@4
EngUnmapEvent
EngUnmapFontFile
; EngUnsecureMem = NTOSKRNL.MmUnsecureVirtualMemory

View file

@ -1,4 +1,4 @@
; $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
;
@ -72,7 +72,7 @@ EngMapFontFile
EngMapModule
EngMarkBandingSurface
EngMovePointer
EngMulDiv
EngMulDiv=EngMulDiv@12
EngMultiByteToUnicodeN
EngMultiByteToWideChar
EngPaint=EngPaint@20
@ -101,7 +101,7 @@ EngTransparentBlt=EngTransparentBlt@32
EngUnicodeToMultiByteN
EngUnloadImage
EngUnlockDriverObj
EngUnlockSurface
EngUnlockSurface=EngUnlockSurface@4
EngUnmapEvent
EngUnmapFontFile
; EngUnsecureMem = NTOSKRNL.MmUnsecureVirtualMemory