diff --git a/reactos/drivers/dd/vga/display/main/enable.c b/reactos/drivers/dd/vga/display/main/enable.c index f0719c49f66..fa4029ac583 100644 --- a/reactos/drivers/dd/vga/display/main/enable.c +++ b/reactos/drivers/dd/vga/display/main/enable.c @@ -1,9 +1,9 @@ /* * entry.c * - * $Revision: 1.23 $ - * $Author: dwelch $ - * $Date: 2002/09/25 21:21:35 $ + * $Revision: 1.24 $ + * $Author: gvg $ + * $Date: 2003/02/25 23:08:52 $ * */ @@ -20,6 +20,7 @@ DRVFN FuncList[] = /* Required Display driver fuctions */ {INDEX_DrvAssertMode, (PFN) DrvAssertMode}, {INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV}, + {INDEX_DrvCopyBits, (PFN) DrvCopyBits}, {INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV}, {INDEX_DrvDisableSurface, (PFN) DrvDisableSurface}, {INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV}, diff --git a/reactos/drivers/dd/vga/display/makefile b/reactos/drivers/dd/vga/display/makefile index 529530c06e5..825e72e76ae 100644 --- a/reactos/drivers/dd/vga/display/makefile +++ b/reactos/drivers/dd/vga/display/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.19 2002/09/25 21:21:35 dwelch Exp $ +# $Id: makefile,v 1.20 2003/02/25 23:08:51 gvg Exp $ PATH_TO_TOP = ../../../.. @@ -18,7 +18,8 @@ OTHER_OBJECTS = \ objects/paint.o \ objects/bitblt.o \ objects/transblt.o \ - objects/offscreen.o + objects/offscreen.o \ + objects/copybits.o VGAVIDEO_OBJECTS = \ vgavideo/vgavideo.o diff --git a/reactos/drivers/dd/vga/display/objects/bitblt.c b/reactos/drivers/dd/vga/display/objects/bitblt.c index 02fd0bc352e..4e4766eede7 100644 --- a/reactos/drivers/dd/vga/display/objects/bitblt.c +++ b/reactos/drivers/dd/vga/display/objects/bitblt.c @@ -369,8 +369,15 @@ DrvBitBlt(SURFOBJ *Dest, BrushPoint, rop4)); case SRCCOPY: - return(VGADDI_BltSrc(Dest, Source, ColorTranslation, DestRect, - SourcePoint)); + if (BMF_4BPP == Source->iBitmapFormat && BMF_4BPP == Dest->iBitmapFormat) + { + return(VGADDI_BltSrc(Dest, Source, ColorTranslation, DestRect, + SourcePoint)); + } + else + { + return FALSE; + } case 0xAACC: return(VGADDI_BltMask(Dest, Mask, ColorTranslation, DestRect, diff --git a/reactos/drivers/dd/vga/display/objects/copybits.c b/reactos/drivers/dd/vga/display/objects/copybits.c new file mode 100644 index 00000000000..242a9ef3199 --- /dev/null +++ b/reactos/drivers/dd/vga/display/objects/copybits.c @@ -0,0 +1,39 @@ +#include "../vgaddi.h" +#include "../vgavideo/vgavideo.h" + +#define DBG +#include + +BOOL STDCALL +DrvCopyBits(OUT PSURFOBJ DestObj, + IN PSURFOBJ SourceObj, + IN PCLIPOBJ ClipObj, + IN PXLATEOBJ XLateObj, + IN PRECTL DestRectL, + IN PPOINTL SrcPointL) +{ + BOOL Done = FALSE; + + if (STYPE_BITMAP == DestObj->iType && BMF_4BPP == DestObj->iBitmapFormat && + STYPE_DEVICE == SourceObj->iType) + { + /* Screen to 4 BPP DIB */ + DIB_BltFromVGA(SrcPointL->x, SrcPointL->y, + DestRectL->right - DestRectL->left, + DestRectL->bottom - DestRectL->top, + DestObj->pvScan0, DestObj->lDelta); + Done = TRUE; + } + else if (STYPE_DEVICE == DestObj->iType && + STYPE_BITMAP == SourceObj->iType && BMF_4BPP == SourceObj->iBitmapFormat) + { + /* 4 BPP DIB to Screen */ + DIB_BltToVGA(DestRectL->left, DestRectL->top, + DestRectL->right - DestRectL->left, + DestRectL->bottom - DestRectL->top, + SourceObj->pvScan0, SourceObj->lDelta); + Done = TRUE; + } + + return Done; +} diff --git a/reactos/drivers/dd/videoprt/videoprt.c b/reactos/drivers/dd/videoprt/videoprt.c index b8b39d2e209..926d93e2b91 100644 --- a/reactos/drivers/dd/videoprt/videoprt.c +++ b/reactos/drivers/dd/videoprt/videoprt.c @@ -1,31 +1,8 @@ -/* $Id: videoprt.c,v 1.2 2003/02/17 21:24:42 gvg Exp $ +/* $Id: videoprt.c,v 1.3 2003/02/25 23:08:52 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 saved. They are filled by VideoPortGetDeviceBase() and - * looked-up by VideoPortMapMemory(). */ #include @@ -34,26 +11,56 @@ #include "../../../ntoskrnl/include/internal/v86m.h" -#include "videoprt.h" - #define NDEBUG #include #define VERSION "0.0.0" +#define TAG_VIDEO_PORT TAG('V', 'I', 'D', 'P') + +typedef struct _VIDEO_PORT_ADDRESS_MAPPING +{ + LIST_ENTRY List; + + PVOID MappedAddress; + ULONG NumberOfUchars; + PHYSICAL_ADDRESS IoAddress; + ULONG SystemIoBusNumber; + UINT MappingCount; +} VIDEO_PORT_ADDRESS_MAPPING, *PVIDEO_PORT_ADDRESS_MAPPING; + +typedef struct _VIDEO_PORT_DEVICE_EXTENSTION +{ + PDEVICE_OBJECT DeviceObject; + PKINTERRUPT InterruptObject; + KSPIN_LOCK InterruptSpinLock; + ULONG InterruptLevel; + KIRQL IRQL; + KAFFINITY Affinity; + PVIDEO_HW_INITIALIZE HwInitialize; + LIST_ENTRY AddressMappingListHead; + INTERFACE_TYPE AdapterInterfaceType; + ULONG SystemIoBusNumber; + UNICODE_STRING RegistryPath; + + UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */ +} VIDEO_PORT_DEVICE_EXTENSION, *PVIDEO_PORT_DEVICE_EXTENSION; + + 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 PVOID STDCALL InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PHYSICAL_ADDRESS IoAddress, + IN ULONG NumberOfUchars, + IN UCHAR InIoSpace); +static VOID STDCALL InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PVOID MappedAddress); static BOOLEAN CsrssInitialized = FALSE; static HANDLE CsrssHandle = 0; static struct _EPROCESS* Csrss = NULL; -/* FIXME: see file header */ -static PDEVICE_OBJECT pdoLastOpened; -static PHYSICAL_ADDRESS Phys1, Phys2; -static PVOID Virt1, Virt2; - PBYTE ReturnCsrssAddress(void) { DPRINT("ReturnCsrssAddress()\n"); @@ -126,7 +133,15 @@ STDCALL VideoPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress) { - DPRINT1("VideoPortFreeDeviceBase not implemented\n"); + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortFreeDeviceBase\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + InternalUnmapMemory(DeviceExtension, MappedAddress); } ULONG @@ -138,11 +153,16 @@ VideoPortGetBusData(IN PVOID HwDeviceExtension, IN ULONG Offset, IN ULONG Length) { - ULONG BusNumber = 0; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; DPRINT("VideoPortGetBusData\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + return HalGetBusDataByOffset(BusDataType, - BusNumber, + DeviceExtension->SystemIoBusNumber, SlotNumber, Buffer, Offset, @@ -164,40 +184,15 @@ VideoPortGetDeviceBase(IN PVOID HwDeviceExtension, IN ULONG NumberOfUchars, IN UCHAR InIoSpace) { - PHYSICAL_ADDRESS TranslatedAddress; - PVOID Virtual; - ULONG AddressSpace; - PVIDEOPORT_EXTENSION_DATA ExtensionData = - MPExtensionToVPExtension(HwDeviceExtension); + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; 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 (0 == Phys1.QuadPart) - { - Virt1 = Virtual; - } - if (0 == Phys2.QuadPart) - { - Virt2 = Virtual; - } - } - } - else - { - return NULL; - } + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + return InternalMapMemory(DeviceExtension, IoAddress, NumberOfUchars, InIoSpace); } VP_STATUS @@ -226,15 +221,20 @@ VideoPortGetAccessRanges(IN PVOID HwDeviceExtension, BOOLEAN FoundDevice; ULONG FunctionNumber; PCI_COMMON_CONFIG Config; - UINT BusNumber = 0; PCM_RESOURCE_LIST AllocatedResources; NTSTATUS Status; UINT AssignedCount; CM_FULL_RESOURCE_DESCRIPTOR *FullList; CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; DPRINT("VideoPortGetAccessRanges\n"); - if (0 == NumRequestedResources) + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + if (0 == NumRequestedResources && PCIBus == DeviceExtension->AdapterInterfaceType) { DPRINT("Looking for VendorId 0x%04x DeviceId 0x%04x\n", (int)*((USHORT *) VendorId), (int)*((USHORT *) DeviceId)); @@ -244,8 +244,9 @@ VideoPortGetAccessRanges(IN PVOID HwDeviceExtension, { PciSlotNumber.u.bits.FunctionNumber = FunctionNumber; if (sizeof(PCI_COMMON_CONFIG) == - HalGetBusDataByOffset(PCIConfiguration, BusNumber, PciSlotNumber.u.AsULONG, - &Config, 0, sizeof(PCI_COMMON_CONFIG))) + HalGetBusDataByOffset(PCIConfiguration, DeviceExtension->SystemIoBusNumber, + PciSlotNumber.u.AsULONG,&Config, 0, + sizeof(PCI_COMMON_CONFIG))) { DPRINT("Slot 0x%02x (Device %d Function %d) VendorId 0x%04x DeviceId 0x%04x\n", PciSlotNumber.u.AsULONG, PciSlotNumber.u.bits.DeviceNumber, @@ -258,7 +259,9 @@ VideoPortGetAccessRanges(IN PVOID HwDeviceExtension, { return STATUS_UNSUCCESSFUL; } - Status = HalAssignSlotResources(NULL, NULL, NULL, NULL, PCIBus, BusNumber, + Status = HalAssignSlotResources(NULL, NULL, NULL, NULL, + DeviceExtension->AdapterInterfaceType, + DeviceExtension->SystemIoBusNumber, PciSlotNumber.u.AsULONG, &AllocatedResources); if (! NT_SUCCESS(Status)) { @@ -271,7 +274,7 @@ VideoPortGetAccessRanges(IN PVOID HwDeviceExtension, FullList++) { assert(FullList->InterfaceType == PCIBus && - FullList->BusNumber == BusNumber && + FullList->BusNumber == DeviceExtension->SystemIoBusNumber && 1 == FullList->PartialResourceList.Version && 1 == FullList->PartialResourceList.Revision); for (Descriptor = FullList->PartialResourceList.PartialDescriptors; @@ -310,6 +313,10 @@ VideoPortGetAccessRanges(IN PVOID HwDeviceExtension, } ExFreePool(AllocatedResources); } + else + { + UNIMPLEMENTED + } return STATUS_SUCCESS; } @@ -324,30 +331,67 @@ VideoPortGetRegistryParameters(IN PVOID HwDeviceExtension, { DPRINT("VideoPortGetRegistryParameters\n"); DPRINT("ParameterName %S\n", ParameterName); - UNIMPLEMENTED; + return STATUS_OBJECT_NAME_NOT_FOUND; +/* + return NO_ERROR; +*/ } +typedef struct _VIDEO_PORT_CONFIG_INFO_TODO { + ULONG Length; + ULONG SystemIoBusNumber; + INTERFACE_TYPE AdapterInterfaceType; + ULONG BusInterruptLevel; + ULONG BusInterruptVector; + KINTERRUPT_MODE InterruptMode; + ULONG NumEmulatorAccessEntries; + PEMULATOR_ACCESS_ENTRY EmulatorAccessEntries; + ULONG_PTR EmulatorAccessEntriesContext; + PHYSICAL_ADDRESS VdmPhysicalVideoMemoryAddress; + ULONG VdmPhysicalVideoMemoryLength; + ULONG HardwareStateSize; + ULONG DmaChannel; + ULONG DmaPort; + UCHAR DmaShareable; + UCHAR InterruptShareable; + BOOLEAN Master; + DMA_WIDTH DmaWidth; + DMA_SPEED DmaSpeed; + BOOLEAN bMapBuffers; + BOOLEAN NeedPhysicalAddresses; + BOOLEAN DemandMode; + ULONG MaximumTransferLength; + ULONG NumberOfPhysicalBreaks; + BOOLEAN ScatterGather; + ULONG MaximumScatterGatherChunkSize; +} VIDEO_PORT_CONFIG_INFO_TODO, *PVIDEO_PORT_CONFIG_INFO_TODO; + ULONG STDCALL VideoPortInitialize(IN PVOID Context1, IN PVOID Context2, IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, IN PVOID HwContext) { + PUNICODE_STRING RegistryPath; UCHAR Again; WCHAR DeviceBuffer[20]; WCHAR SymlinkBuffer[20]; + WCHAR DeviceVideoBuffer[20]; NTSTATUS Status; PDRIVER_OBJECT MPDriverObject = (PDRIVER_OBJECT) Context1; PDEVICE_OBJECT MPDeviceObject; - VIDEO_PORT_CONFIG_INFO ConfigInfo; - PVIDEOPORT_EXTENSION_DATA ExtensionData; + VIDEO_PORT_CONFIG_INFO_TODO ConfigInfo; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; ULONG DeviceNumber = 0; UNICODE_STRING DeviceName; UNICODE_STRING SymlinkName; - CLIENT_ID Cid; + ULONG MaxBus; + ULONG MaxLen; DPRINT("VideoPortInitialize\n"); + RegistryPath = (PUNICODE_STRING) Context2; + /* Build Dispatch table from passed data */ MPDriverObject->DriverStartIo = (PDRIVER_STARTIO) HwInitializationData->HwStartIO; @@ -361,7 +405,7 @@ VideoPortInitialize(IN PVOID Context1, /* Create the device */ Status = IoCreateDevice(MPDriverObject, HwInitializationData->HwDeviceExtensionSize + - sizeof(VIDEOPORT_EXTENSION_DATA), + sizeof(VIDEO_PORT_DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_VIDEO, 0, @@ -375,11 +419,73 @@ VideoPortInitialize(IN PVOID Context1, MPDriverObject->DeviceObject = MPDeviceObject; - /* initialize the miniport drivers dispatch table */ + /* 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; + /* Initialize our device extension */ + DeviceExtension = + (PVIDEO_PORT_DEVICE_EXTENSION) MPDeviceObject->DeviceExtension; + DeviceExtension->DeviceObject = MPDeviceObject; + DeviceExtension->HwInitialize = HwInitializationData->HwInitialize; + DeviceExtension->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType; + DeviceExtension->SystemIoBusNumber = 0; + MaxLen = (wcslen(RegistryPath->Buffer) + 10) * sizeof(WCHAR); + DeviceExtension->RegistryPath.MaximumLength = MaxLen; + DeviceExtension->RegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool, + MaxLen, + TAG_VIDEO_PORT); + swprintf(DeviceExtension->RegistryPath.Buffer, L"%s\\Device%d", + RegistryPath->Buffer, DeviceNumber); + DeviceExtension->RegistryPath.Length = wcslen(DeviceExtension->RegistryPath.Buffer) * + sizeof(WCHAR); + + MaxBus = (DeviceExtension->AdapterInterfaceType == PCIBus) ? 8 : 1; + DPRINT("MaxBus: %lu\n", MaxBus); + InitializeListHead(&DeviceExtension->AddressMappingListHead); + + /* Set the buffering strategy here... */ + /* If you change this, remember to change VidDispatchDeviceControl too */ + MPDeviceObject->Flags |= DO_BUFFERED_IO; + + do + { + RtlZeroMemory(&DeviceExtension->MiniPortDeviceExtension, + HwInitializationData->HwDeviceExtensionSize); + DPRINT("Searching on bus %d\n", DeviceExtension->SystemIoBusNumber); + /* Setup configuration info */ + RtlZeroMemory(&ConfigInfo, sizeof(VIDEO_PORT_CONFIG_INFO_TODO)); + ConfigInfo.Length = sizeof(VIDEO_PORT_CONFIG_INFO_TODO); + ConfigInfo.AdapterInterfaceType = DeviceExtension->AdapterInterfaceType; + ConfigInfo.SystemIoBusNumber = DeviceExtension->SystemIoBusNumber; + ConfigInfo.InterruptMode = (PCIBus == DeviceExtension->AdapterInterfaceType) ? + LevelSensitive : Latched; + + /* Call HwFindAdapter entry point */ + /* FIXME: Need to figure out what string to pass as param 3 */ + Status = HwInitializationData->HwFindAdapter(&DeviceExtension->MiniPortDeviceExtension, + Context2, + NULL, + &ConfigInfo, + &Again); + if (NO_ERROR != Status) + { + DPRINT("HwFindAdapter call failed with error %d\n", Status); + DeviceExtension->SystemIoBusNumber++; + } + } + while (NO_ERROR != Status && DeviceExtension->SystemIoBusNumber < MaxBus); + + if (NO_ERROR != Status) + { + RtlFreeUnicodeString(&DeviceExtension->RegistryPath); + IoDeleteDevice(MPDeviceObject); + + return Status; + } + DPRINT("Found adapter\n"); + /* create symbolic link "\??\DISPLAYx" */ swprintf(SymlinkBuffer, L"\\??\\DISPLAY%lu", DeviceNumber+1); RtlInitUnicodeString (&SymlinkName, @@ -387,36 +493,14 @@ VideoPortInitialize(IN PVOID Context1, 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); + /* Add entry to DEVICEMAP\VIDEO key in registry */ + swprintf(DeviceVideoBuffer, L"\\Device\\Video%d", DeviceNumber); + RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP, + L"VIDEO", + DeviceVideoBuffer, + REG_SZ, + DeviceExtension->RegistryPath.Buffer, + DeviceExtension->RegistryPath.Length + sizeof(WCHAR)); /* FIXME: Allocate hardware resources for device */ @@ -426,26 +510,26 @@ VideoPortInitialize(IN PVOID Context1, ConfigInfo.BusInterruptVector == 0)) { #if 0 - ExtensionData->IRQL = ConfigInfo.BusInterruptLevel; - ExtensionData->InterruptLevel = + DeviceExtension->IRQL = ConfigInfo.BusInterruptLevel; + DeviceExtension->InterruptLevel = HalGetInterruptVector(ConfigInfo.AdapterInterfaceType, ConfigInfo.SystemIoBusNumber, ConfigInfo.BusInterruptLevel, ConfigInfo.BusInterruptVector, - &ExtensionData->IRQL, - &ExtensionData->Affinity); - KeInitializeSpinLock(&ExtensionData->InterruptSpinLock); - Status = IoConnectInterrupt(&ExtensionData->InterruptObject, + &DeviceExtension->IRQL, + &DeviceExtension->Affinity); + KeInitializeSpinLock(&DeviceExtension->InterruptSpinLock); + Status = IoConnectInterrupt(&DeviceExtension->InterruptObject, (PKSERVICE_ROUTINE) HwInitializationData->HwInterrupt, - VPExtensionToMPExtension(ExtensionData), - &ExtensionData->InterruptSpinLock, - ExtensionData->InterruptLevel, - ExtensionData->IRQL, - ExtensionData->IRQL, + &DeviceExtension->MiniPortDeviceExtension, + &DeviceExtension->InterruptSpinLock, + DeviceExtension->InterruptLevel, + DeviceExtension->IRQL, + DeviceExtension->IRQL, ConfigInfo.InterruptMode, FALSE, - ExtensionData->Affinity, + DeviceExtension->Affinity, FALSE); if (!NT_SUCCESS(Status)) { @@ -466,14 +550,14 @@ VideoPortInitialize(IN PVOID Context1, Status = IoInitializeTimer(MPDeviceObject, (PIO_TIMER_ROUTINE) HwInitializationData->HwTimer, - VPExtensionToMPExtension(ExtensionData)); + &DeviceExtension->MiniPortDeviceExtension); if (!NT_SUCCESS(Status)) { DPRINT("IoInitializeTimer failed with status 0x%08x\n", Status); if (HwInitializationData->HwInterrupt != NULL) { - IoDisconnectInterrupt(ExtensionData->InterruptObject); + IoDisconnectInterrupt(DeviceExtension->InterruptObject); } IoDeleteDevice(MPDeviceObject); @@ -544,46 +628,19 @@ VideoPortMapMemory(IN PVOID HwDeviceExtension, IN PULONG InIoSpace, OUT PVOID *VirtualAddress) { - PHYSICAL_ADDRESS TranslatedAddress; - ULONG AddressSpace; - PVIDEOPORT_EXTENSION_DATA ExtensionData = - MPExtensionToVPExtension(HwDeviceExtension); + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; + PLIST_ENTRY Entry; DPRINT("VideoPortMapMemory\n"); - /* FIXME: see file header */ - if (Phys1.QuadPart == PhysicalAddress.QuadPart) - { - DPRINT("Using saved mapping #1\n"); - *VirtualAddress = Virt1; - return STATUS_SUCCESS; - } - if (Phys2.QuadPart == PhysicalAddress.QuadPart) - { - DPRINT("Using saved mapping #2\n"); - *VirtualAddress = Virt2; - return STATUS_SUCCESS; - } + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + *VirtualAddress = InternalMapMemory(DeviceExtension, PhysicalAddress, + *Length, *InIoSpace); - 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; - } + return NULL == *VirtualAddress ? STATUS_NO_MEMORY : STATUS_SUCCESS; } UCHAR @@ -730,8 +787,21 @@ VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension, IN PVOID ValueData, IN ULONG ValueLength) { - DPRINT1("VideoPortSetRegistryParameters not implemented\n"); - return NO_ERROR; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoSetRegistryParameters\n"); + + assert_irql(PASSIVE_LEVEL); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + return RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE, + DeviceExtension->RegistryPath.Buffer, + ValueName, + REG_BINARY, + ValueData, + ValueLength); } VP_STATUS @@ -748,22 +818,28 @@ VOID STDCALL VideoPortStartTimer(IN PVOID HwDeviceExtension) { - PVIDEOPORT_EXTENSION_DATA ExtensionData = - MPExtensionToVPExtension(HwDeviceExtension); + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; DPRINT("VideoPortStartTimer\n"); - IoStartTimer(ExtensionData->DeviceObject); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + IoStartTimer(DeviceExtension->DeviceObject); } VOID STDCALL VideoPortStopTimer(IN PVOID HwDeviceExtension) { - PVIDEOPORT_EXTENSION_DATA ExtensionData = - MPExtensionToVPExtension(HwDeviceExtension); + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; DPRINT("VideoPortStopTimer\n"); - IoStopTimer(ExtensionData->DeviceObject); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + IoStopTimer(DeviceExtension->DeviceObject); } BOOLEAN @@ -783,8 +859,17 @@ VideoPortUnmapMemory(IN PVOID HwDeviceExtension, IN PVOID VirtualAddress, IN HANDLE ProcessHandle) { - DPRINT1("VideoPortUnmapMemory not implemented\n"); - return NO_ERROR; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; + + DPRINT("VideoPortFreeDeviceBase\n"); + + DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, + VIDEO_PORT_DEVICE_EXTENSION, + MiniPortDeviceExtension); + + InternalUnmapMemory(DeviceExtension, VirtualAddress); + + return STATUS_SUCCESS; } VP_STATUS @@ -820,7 +905,9 @@ STDCALL VideoPortWritePortUlong(IN PULONG Port, IN ULONG Value) { +#ifdef TODO DPRINT("VideoPortWritePortUlong\n"); +#endif WRITE_PORT_ULONG(Port, Value); } @@ -914,7 +1001,7 @@ VideoPortZeroDeviceMemory(OUT PVOID Destination, IN ULONG Length) { DPRINT("VideoPortZeroDeviceMemory\n"); - UNIMPLEMENTED; + RtlZeroMemory(Destination, Length); } @@ -940,13 +1027,10 @@ VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack; - PVIDEOPORT_EXTENSION_DATA ExtensionData; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; 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 && @@ -956,8 +1040,8 @@ VidDispatchOpenClose(IN PDEVICE_OBJECT pDO, Csrss = PsGetCurrentProcess(); CsrssInitialized = TRUE; DPRINT("Csrss %p\n", Csrss); - ExtensionData = (PVIDEOPORT_EXTENSION_DATA) pDO->DeviceExtension; - if (ExtensionData->HwInitialize(VPExtensionToMPExtension(ExtensionData))) + DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION) pDO->DeviceExtension; + if (DeviceExtension->HwInitialize(&DeviceExtension->MiniPortDeviceExtension)) { Irp->IoStatus.Status = STATUS_SUCCESS; } @@ -1020,37 +1104,144 @@ VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack; + PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension; 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); + DeviceExtension = DeviceObject->DeviceExtension; - // Translate the IRP to a VRP + /* Translate the IRP to a VRP */ vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET)); - vrp->StatusBlock = ExAllocatePool(PagedPool, sizeof(STATUS_BLOCK)); + if (NULL == vrp) + { + return STATUS_NO_MEMORY; + } + vrp->StatusBlock = (PSTATUS_BLOCK) &(Irp->IoStatus); vrp->IoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; - // We're assuming METHOD_BUFFERED + /* We're assuming METHOD_BUFFERED */ vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer; vrp->InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; - vrp->OutputBuffer = Irp->UserBuffer; + vrp->OutputBuffer = Irp->AssociatedIrp.SystemBuffer; vrp->OutputBufferLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; - // Call the Miniport Driver with the VRP - DeviceObject->DriverObject->DriverStartIo(VPExtensionToMPExtension(DeviceObject->DeviceExtension), (PIRP)vrp); + /* Call the Miniport Driver with the VRP */ + DeviceObject->DriverObject->DriverStartIo((PVOID) &DeviceExtension->MiniPortDeviceExtension, (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); + /* Free the VRP */ ExFreePool(vrp); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; } + +static PVOID STDCALL +InternalMapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PHYSICAL_ADDRESS IoAddress, + IN ULONG NumberOfUchars, + IN UCHAR InIoSpace) +{ + PHYSICAL_ADDRESS TranslatedAddress; + PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; + ULONG AddressSpace; + PVOID MappedAddress; + PLIST_ENTRY Entry; + INTERFACE_TYPE BusType = PCIBus; + + if (0 != (InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE)) + { + DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n"); + InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE; + } + if (! IsListEmpty(&DeviceExtension->AddressMappingListHead)) + { + Entry = DeviceExtension->AddressMappingListHead.Flink; + while (Entry != &DeviceExtension->AddressMappingListHead) + { + AddressMapping = CONTAINING_RECORD(Entry, + VIDEO_PORT_ADDRESS_MAPPING, + List); + if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart && + NumberOfUchars <= AddressMapping->NumberOfUchars) + { + AddressMapping->MappingCount++; + return AddressMapping->MappedAddress; + } + Entry = Entry->Flink; + } + } + + AddressSpace = (ULONG)InIoSpace; + if (HalTranslateBusAddress(BusType, + DeviceExtension->SystemIoBusNumber, + IoAddress, + &AddressSpace, + &TranslatedAddress) == FALSE) + return NULL; + + /* i/o space */ + if (AddressSpace != 0) + { + assert(0 == TranslatedAddress.u.HighPart); + return (PVOID) TranslatedAddress.u.LowPart; + } + + MappedAddress = MmMapIoSpace(TranslatedAddress, + NumberOfUchars, + FALSE); + + AddressMapping = ExAllocatePoolWithTag(PagedPool, + sizeof(VIDEO_PORT_ADDRESS_MAPPING), + TAG_VIDEO_PORT); + if (AddressMapping == NULL) + return MappedAddress; + + AddressMapping->MappedAddress = MappedAddress; + AddressMapping->NumberOfUchars = NumberOfUchars; + AddressMapping->IoAddress = IoAddress; + AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber; + AddressMapping->MappingCount = 1; + + InsertHeadList(&DeviceExtension->AddressMappingListHead, + &AddressMapping->List); + + return MappedAddress; +} + +static VOID STDCALL +InternalUnmapMemory(IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension, + IN PVOID MappedAddress) +{ + PVIDEO_PORT_ADDRESS_MAPPING AddressMapping; + PLIST_ENTRY Entry; + + Entry = DeviceExtension->AddressMappingListHead.Flink; + while (Entry != &DeviceExtension->AddressMappingListHead) + { + AddressMapping = CONTAINING_RECORD(Entry, + VIDEO_PORT_ADDRESS_MAPPING, + List); + if (AddressMapping->MappedAddress == MappedAddress) + { + assert(0 <= AddressMapping->MappingCount); + AddressMapping->MappingCount--; + if (0 == AddressMapping->MappingCount) + { +#ifdef TODO + MmUnmapIoSpace(AddressMapping->MappedAddress, + AddressMapping->NumberOfUchars); +#else +DPRINT1("MmUnmapIoSpace(0x%08x, 0x%08x)\n", AddressMapping->MappedAddress, AddressMapping->NumberOfUchars); +#endif + RemoveEntryList(Entry); + ExFreePool(AddressMapping); + + return; + } + } + + Entry = Entry->Flink; + } +} diff --git a/reactos/drivers/dd/videoprt/videoprt.h b/reactos/drivers/dd/videoprt/videoprt.h index 01be32e933c..e69de29bb2d 100644 --- a/reactos/drivers/dd/videoprt/videoprt.h +++ b/reactos/drivers/dd/videoprt/videoprt.h @@ -1,17 +0,0 @@ - -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))) - diff --git a/reactos/install.bat b/reactos/install.bat index 33b6c7d700c..377a7c0a665 100644 --- a/reactos/install.bat +++ b/reactos/install.bat @@ -50,7 +50,7 @@ copy drivers\dd\null\null.sys %ROS_INSTALL%\system32\drivers copy drivers\dd\serial\serial.sys %ROS_INSTALL%\system32\drivers copy drivers\dd\serenum\serenum.sys %ROS_INSTALL%\system32\drivers copy drivers\dd\vga\miniport\vgamp.sys %ROS_INSTALL%\system32\drivers -copy drivers\dd\vga\display\vgaddi.dll %ROS_INSTALL%\system32\drivers +copy drivers\dd\vga\display\vgaddi.dll %ROS_INSTALL%\system32 copy drivers\dd\videoprt\videoprt.sys %ROS_INSTALL%\system32\drivers copy drivers\net\afd\afd.sys %ROS_INSTALL%\system32\drivers copy drivers\net\dd\ne2000\ne2000.sys %ROS_INSTALL%\system32\drivers @@ -97,7 +97,7 @@ copy lib\wsock32\wsock32.dll %ROS_INSTALL%\system32 copy subsys\smss\smss.exe %ROS_INSTALL%\system32 copy subsys\csrss\csrss.exe %ROS_INSTALL%\system32 copy subsys\ntvdm\ntvdm.exe %ROS_INSTALL%\system32 -copy subsys\win32k\win32k.sys %ROS_INSTALL%\system32\drivers +copy subsys\win32k\win32k.sys %ROS_INSTALL%\system32 copy subsys\system\usetup\usetup.exe %ROS_INSTALL%\system32 copy apps\utils\cat\cat.exe %ROS_INSTALL%\bin copy apps\utils\partinfo\partinfo.exe %ROS_INSTALL%\bin diff --git a/reactos/subsys/smss/init.c b/reactos/subsys/smss/init.c index 677e85be6e8..8443b1c8fba 100644 --- a/reactos/subsys/smss/init.c +++ b/reactos/subsys/smss/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.44 2002/09/08 10:23:46 chorns Exp $ +/* $Id: init.c,v 1.45 2003/02/25 23:08:52 gvg Exp $ * * init.c - Session Manager initialization * @@ -561,7 +561,7 @@ SmLoadSubsystems(VOID) /* Load kernel mode subsystem (aka win32k.sys) */ RtlInitUnicodeStringFromLiteral(&ImageInfo.ModuleName, - L"\\SystemRoot\\system32\\drivers\\win32k.sys"); + L"\\SystemRoot\\system32\\win32k.sys"); Status = NtSetSystemInformation(SystemLoadAndCallImage, &ImageInfo, diff --git a/reactos/subsys/win32k/dib/dib4bpp.c b/reactos/subsys/win32k/dib/dib4bpp.c index 856ea0d537a..131e59a219d 100644 --- a/reactos/subsys/win32k/dib/dib4bpp.c +++ b/reactos/subsys/win32k/dib/dib4bpp.c @@ -30,7 +30,7 @@ PFN_DIB_HLine DIB_4BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c PBYTE addr = SurfObj->pvBits + (x1>>1) + y * SurfObj->lDelta; LONG cx = x1; - while(cx <= x2) { + while(cx < x2) { *addr = (*addr & notmask[x1&1]) | (c << ((1-(x1&1))<<2)); if((++x1 & 1) == 0) ++addr; @@ -44,7 +44,7 @@ PFN_DIB_VLine DIB_4BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c int lDelta = SurfObj->lDelta; addr += (x>>1) + y1 * lDelta; - while(y1++ <= y2) { + while(y1++ < y2) { *addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2)); addr += lDelta; } diff --git a/reactos/subsys/win32k/eng/bitblt.c b/reactos/subsys/win32k/eng/bitblt.c index b582cb0cbae..03eb968457d 100644 --- a/reactos/subsys/win32k/eng/bitblt.c +++ b/reactos/subsys/win32k/eng/bitblt.c @@ -15,11 +15,13 @@ #include "clip.h" #include "objects.h" #include "../dib/dib.h" +#include "misc.h" #include #include #include #include #include +#include #define NDEBUG #include @@ -123,7 +125,6 @@ BltPatCopy(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask, 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)) @@ -144,7 +145,6 @@ BltPatCopy(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask, DbgPrint("BltPatCopy: unsupported DIB format %u (bitsPerPixel:%u)\n", Dest->iBitmapFormat, BitsPerFormat(Dest->iBitmapFormat)); - MouseSafetyOnDrawEnd(Dest, DestGDI); return FALSE; } @@ -153,7 +153,6 @@ BltPatCopy(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask, { DIB_HLine(Dest, DestRect->left, DestRect->right, y, Brush->iSolidColor); } - MouseSafetyOnDrawEnd(Dest, DestGDI); return TRUE; } @@ -161,8 +160,8 @@ BltPatCopy(SURFOBJ *Dest, PSURFGDI DestGDI, SURFOBJ *Mask, INT abs(INT nm); BOOL STDCALL -EngBitBlt(SURFOBJ *Dest, - SURFOBJ *Source, +EngBitBlt(SURFOBJ *DestObj, + SURFOBJ *SourceObj, SURFOBJ *Mask, CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation, @@ -173,106 +172,92 @@ EngBitBlt(SURFOBJ *Dest, POINTL *BrushOrigin, ROP4 rop4) { - BOOLEAN ret; - BYTE clippingType; - RECTL rclTmp; - POINTL ptlTmp; - RECT_ENUM RectEnum; - BOOL EnumMore; - PSURFGDI DestGDI, SourceGDI; - HSURF hTemp; - PSURFOBJ TempSurf = NULL; - BOOLEAN canCopyBits; - POINTL TempPoint; - RECTL TempRect; - SIZEL TempSize; + BOOLEAN ret; + BYTE clippingType; + RECTL rclTmp; + POINTL ptlTmp; + RECT_ENUM RectEnum; + BOOL EnumMore; + PSURFGDI OutputGDI, InputGDI; + POINTL InputPoint; + RECTL InputRect; + RECTL OutputRect; + POINTL Translate; + INTENG_ENTER_LEAVE EnterLeaveSource; + INTENG_ENTER_LEAVE EnterLeaveDest; + PSURFOBJ InputObj; + PSURFOBJ OutputObj; - if(Source != NULL) SourceGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Source); - if(Dest != NULL) DestGDI = (PSURFGDI)AccessInternalObjectFromUserObject(Dest); - - if (Source != NULL) + /* Check for degenerate case: if height or width of DestRect is 0 pixels there's + nothing to do */ + if (DestRect->right == DestRect->left || DestRect->bottom == DestRect->top) { - MouseSafetyOnDrawStart(Source, SourceGDI, SourcePoint->x, SourcePoint->y, - (SourcePoint->x + abs(DestRect->right - DestRect->left)), - (SourcePoint->y + abs(DestRect->bottom - DestRect->top))); + return TRUE; } - MouseSafetyOnDrawStart(Dest, DestGDI, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); - // If we don't have to do anything special, we can punt to DrvCopyBits - // if it exists - if( (Mask == NULL) && (MaskOrigin == NULL) && (Brush == NULL) && - (BrushOrigin == NULL) && (rop4 == 0) ) - { - canCopyBits = TRUE; - } else - canCopyBits = FALSE; - - // Check for CopyBits or BitBlt hooks if one is not a GDI managed bitmap, IF: - // * The destination bitmap is not managed by the GDI OR - if(Dest->iType != STYPE_BITMAP) - { - // Destination surface is device managed - if (DestGDI->BitBlt!=NULL) + if (NULL != SourcePoint) { - if (Source!=NULL) - { - // Get the source into a format compatible surface - TempPoint.x = 0; - TempPoint.y = 0; - TempRect.top = 0; - TempRect.left = 0; - TempRect.bottom = DestRect->bottom - DestRect->top; - TempRect.right = DestRect->right - DestRect->left; - TempSize.cx = TempRect.right; - TempSize.cy = TempRect.bottom; - - hTemp = EngCreateBitmap(TempSize, - DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)), - Dest->iBitmapFormat, 0, NULL); - TempSurf = (PSURFOBJ)AccessUserObject((ULONG)hTemp); - - // FIXME: Skip creating a TempSurf if we have the same BPP and palette - EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0); - } - - ret = DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion, - NULL, DestRect, &TempPoint, - MaskOrigin, Brush, BrushOrigin, rop4); - - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); - - return ret; + InputRect.left = SourcePoint->x; + InputRect.right = SourcePoint->x + (DestRect->right - DestRect->left); + InputRect.top = SourcePoint->y; + InputRect.bottom = SourcePoint->y + (DestRect->bottom - DestRect->top); + } + else + { + InputRect.left = 0; + InputRect.right = DestRect->right - DestRect->left; + InputRect.top = 0; + InputRect.bottom = DestRect->bottom - DestRect->top; + } + + if (! IntEngEnter(&EnterLeaveSource, SourceObj, &InputRect, TRUE, &Translate, &InputObj)) + { + return FALSE; + } + + if (NULL != SourcePoint) + { + InputPoint.x = SourcePoint->x + Translate.x; + InputPoint.y = SourcePoint->y + Translate.y; + } + else + { + InputPoint.x = 0; + InputPoint.y = 0; + } + + if (NULL != InputObj) + { + InputGDI = (PSURFGDI) AccessInternalObjectFromUserObject(InputObj); + } + + OutputRect = *DestRect; + + if (! IntEngEnter(&EnterLeaveDest, DestObj, &OutputRect, FALSE, &Translate, &OutputObj)) + { + IntEngLeave(&EnterLeaveSource); + return FALSE; + } + + OutputRect.left = DestRect->left + Translate.x; + OutputRect.right = DestRect->right + Translate.x; + OutputRect.top = DestRect->top + Translate.y; + OutputRect.bottom = DestRect->bottom + Translate.y; + + + if (NULL != OutputObj) + { + OutputGDI = (PSURFGDI)AccessInternalObjectFromUserObject(OutputObj); } - } /* 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 && 0xaacc != rop4 && PATCOPY != rop4) + if (NULL == InputObj && 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(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, - MaskOrigin, Brush, BrushOrigin, rop4); - - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); - - return ret; - - // Convert the surface from the driver into the required destination surface - } - } - // Determine clipping type if (ClipRegion == (CLIPOBJ *) NULL) { @@ -283,9 +268,15 @@ EngBitBlt(SURFOBJ *Dest, if (0xaacc == rop4) { - return BltMask(Dest, DestGDI, Mask, DestRect, MaskOrigin, Brush, BrushOrigin); + ret = BltMask(OutputObj, OutputGDI, Mask, &OutputRect, MaskOrigin, Brush, BrushOrigin); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); + return ret; } else if (PATCOPY == rop4) { - return BltPatCopy(Dest, DestGDI, Mask, DestRect, MaskOrigin, Brush, BrushOrigin); + ret = BltPatCopy(OutputObj, OutputGDI, Mask, &OutputRect, MaskOrigin, Brush, BrushOrigin); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); + return ret; } @@ -293,23 +284,23 @@ EngBitBlt(SURFOBJ *Dest, switch(clippingType) { case DC_TRIVIAL: - CopyBitsCopy(Dest, Source, DestGDI, SourceGDI, DestRect, SourcePoint, Source->lDelta, ColorTranslation); + CopyBitsCopy(OutputObj, InputObj, OutputGDI, InputGDI, &OutputRect, &InputPoint, InputObj->lDelta, ColorTranslation); - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); return(TRUE); case DC_RECT: // Clip the blt to the clip rectangle - EngIntersectRect(&rclTmp, DestRect, &ClipRegion->rclBounds); + EngIntersectRect(&rclTmp, &OutputRect, &ClipRegion->rclBounds); - ptlTmp.x = SourcePoint->x + rclTmp.left - DestRect->left; - ptlTmp.y = SourcePoint->y + rclTmp.top - DestRect->top; + ptlTmp.x = InputPoint.x + rclTmp.left - OutputRect.left; + ptlTmp.y = InputPoint.y + rclTmp.top - OutputRect.top; - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); return(TRUE); @@ -326,10 +317,10 @@ EngBitBlt(SURFOBJ *Dest, RECTL* prcl = &RectEnum.arcl[0]; do { - EngIntersectRect(prcl, prcl, DestRect); + EngIntersectRect(prcl, prcl, &OutputRect); - ptlTmp.x = SourcePoint->x + prcl->left - DestRect->left; - ptlTmp.y = SourcePoint->y + prcl->top - DestRect->top; + ptlTmp.x = InputPoint.x + prcl->left - OutputRect.left; + ptlTmp.y = InputPoint.y + prcl->top - OutputRect.top; prcl++; @@ -338,14 +329,65 @@ EngBitBlt(SURFOBJ *Dest, } while(EnumMore); - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); return(TRUE); } - MouseSafetyOnDrawEnd(Source, SourceGDI); - MouseSafetyOnDrawEnd(Dest, DestGDI); + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); return(FALSE); } + +BOOL STDCALL +IntEngBitBlt(SURFOBJ *DestObj, + SURFOBJ *SourceObj, + SURFOBJ *Mask, + CLIPOBJ *ClipRegion, + XLATEOBJ *ColorTranslation, + RECTL *DestRect, + POINTL *SourcePoint, + POINTL *MaskOrigin, + BRUSHOBJ *Brush, + POINTL *BrushOrigin, + ROP4 rop4) +{ + BOOLEAN ret; + SURFGDI *DestGDI; + SURFGDI *SourceGDI; + + if (NULL != SourceObj) + { + SourceGDI = (PSURFGDI) AccessInternalObjectFromUserObject(SourceObj); + MouseSafetyOnDrawStart(SourceObj, SourceGDI, SourcePoint->x, SourcePoint->y, + (SourcePoint->x + abs(DestRect->right - DestRect->left)), + (SourcePoint->y + abs(DestRect->bottom - DestRect->top))); + } + + /* No success yet */ + ret = FALSE; + DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj); + MouseSafetyOnDrawStart(DestObj, DestGDI, DestRect->left, DestRect->top, + DestRect->right, DestRect->bottom); + + /* Call the driver's DrvBitBlt if available */ + if (NULL != DestGDI->BitBlt) { + ret = DestGDI->BitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, + DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, rop4); + } + + if (! ret) { + ret = EngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, + DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, rop4); + } + + MouseSafetyOnDrawEnd(DestObj, DestGDI); + if (NULL != SourceObj) + { + MouseSafetyOnDrawEnd(SourceObj, SourceGDI); + } + + return ret; +} diff --git a/reactos/subsys/win32k/eng/lineto.c b/reactos/subsys/win32k/eng/lineto.c index ad94024ae24..94b0b3ec4d4 100644 --- a/reactos/subsys/win32k/eng/lineto.c +++ b/reactos/subsys/win32k/eng/lineto.c @@ -1,14 +1,16 @@ #include #include +#include #include "objects.h" #include "../dib/dib.h" +#include "misc.h" #include #include #include BOOL STDCALL -EngLineTo(SURFOBJ *Surface, +EngLineTo(SURFOBJ *DestObj, CLIPOBJ *Clip, BRUSHOBJ *Brush, LONG x1, @@ -18,8 +20,12 @@ EngLineTo(SURFOBJ *Surface, RECTL *RectBounds, MIX mix) { - LONG x, y, deltax, deltay, i, length, xchange, ychange, error, hx, vy; + LONG x, y, deltax, deltay, i, xchange, ychange, error, hx, vy; ULONG Pixel = Brush->iSolidColor; + SURFOBJ *OutputObj; + RECTL DestRect; + POINTL Translate; + INTENG_ENTER_LEAVE EnterLeave; // These functions are assigned if we're working with a DIB // The assigned functions depend on the bitsPerPixel of the DIB @@ -27,9 +33,38 @@ EngLineTo(SURFOBJ *Surface, PFN_DIB_HLine DIB_HLine; PFN_DIB_VLine DIB_VLine; + DestRect.left = x1; + if (x1 != x2) + { + DestRect.right = x2; + } + else + { + DestRect.right = x2 + 1; + } + DestRect.top = y1; + if (y1 != y2) + { + DestRect.bottom = y2; + } + else + { + DestRect.bottom = y2 + 1; + } + + if (! IntEngEnter(&EnterLeave, DestObj, &DestRect, FALSE, &Translate, &OutputObj)) + { + return FALSE; + } + + x1 += Translate.x; + x2 += Translate.x; + y1 += Translate.y; + y2 += Translate.y; + // Assign DIB functions according to bytes per pixel - switch(BitsPerFormat(Surface->iBitmapFormat)) - { + switch(BitsPerFormat(OutputObj->iBitmapFormat)) + { case 1: DIB_PutPixel = (PFN_DIB_PutPixel)DIB_1BPP_PutPixel; DIB_HLine = (PFN_DIB_HLine)DIB_1BPP_HLine; @@ -55,83 +90,89 @@ EngLineTo(SURFOBJ *Surface, break; default: - DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", Surface->iBitmapFormat, - BitsPerFormat(Surface->iBitmapFormat)); + DbgPrint("EngLineTo: unsupported DIB format %u (bitsPerPixel:%u)\n", OutputObj->iBitmapFormat, + BitsPerFormat(OutputObj->iBitmapFormat)); return FALSE; - } + } // FIXME: Implement clipping - x=x1; - y=y1; - deltax=x2-x1; - deltay=y2-y1; + x = x1; + y = y1; + deltax = x2 - x1; + deltay = y2 - y1; - if(deltax<0) - { - xchange=-1; - deltax=-deltax; + if (deltax < 0) + { + xchange = -1; + deltax = - deltax; hx = x2; - } else - { - xchange=1; + } + else + { + xchange = 1; hx = x1; - } + } - if(deltay<0) - { - ychange=-1; - deltay=-deltay; + if (deltay < 0) + { + ychange = -1; + deltay = - deltay; vy = y2; - } else - { - ychange=1; + } + else + { + ychange = 1; vy = y1; - } - - 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; - - if(deltaxdeltay) - { - x=x+xchange; - error=error-deltay; - } - i=i+1; } - } else - { - length=deltax+1; - while(ideltax) - { - y=y+ychange; - error=error-deltax; - } - i=i+1; - } - } - return TRUE; + if (y1 == y2) + { + DIB_HLine(OutputObj, hx, hx + deltax, y1, Pixel); + } + else if(x1==x2) + { + DIB_VLine(OutputObj, x1, vy, vy + deltay, Pixel); + } + else + { + error = 0; + + if (deltax < deltay) + { + for (i = 0; i < deltay; i++) + { + DIB_PutPixel(OutputObj, x, y, Pixel); + y = y + ychange; + error = error + deltax; + + if (deltay < error) + { + x = x + xchange; + error = error - deltay; + } + } + } + else + { + for (i = 0; i < deltax; i++) + { + DIB_PutPixel(OutputObj, x, y, Pixel); + x = x + xchange; + error = error + deltay; + if (error > deltax) + { + y = y + ychange; + error = error - deltax; + } + } + } + } + + return IntEngLeave(&EnterLeave); } BOOL STDCALL -IntEngLineTo(SURFOBJ *Surface, +IntEngLineTo(SURFOBJ *DestSurf, CLIPOBJ *Clip, BRUSHOBJ *Brush, LONG x1, @@ -146,13 +187,13 @@ IntEngLineTo(SURFOBJ *Surface, /* No success yet */ ret = FALSE; - SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(Surface); + SurfGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestSurf); - MouseSafetyOnDrawStart(Surface, SurfGDI, x1, y1, x2, y2); + MouseSafetyOnDrawStart(DestSurf, 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); + ret = SurfGDI->LineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); } #if 0 @@ -162,10 +203,10 @@ IntEngLineTo(SURFOBJ *Surface, #endif if (! ret) { - ret = EngLineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); + ret = EngLineTo(DestSurf, Clip, Brush, x1, y1, x2, y2, RectBounds, mix); } - MouseSafetyOnDrawEnd(Surface, SurfGDI); + MouseSafetyOnDrawEnd(DestSurf, SurfGDI); return ret; } diff --git a/reactos/subsys/win32k/eng/misc.c b/reactos/subsys/win32k/eng/misc.c new file mode 100644 index 00000000000..3e6b14c567a --- /dev/null +++ b/reactos/subsys/win32k/eng/misc.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include "misc.h" +#include "objects.h" + +BOOL STDCALL +IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, + SURFOBJ *DestObj, + RECTL *DestRect, + BOOL ReadOnly, + POINTL *Translate, + SURFOBJ **OutputObj) +{ + LONG Exchange; + SIZEL BitmapSize; + POINTL SrcPoint; + LONG Width; + + /* Normalize */ + if (DestRect->right < DestRect->left) + { + Exchange = DestRect->left; + DestRect->left = DestRect->right; + DestRect->right = Exchange; + } + if (DestRect->bottom < DestRect->top) + { + Exchange = DestRect->top; + DestRect->top = DestRect->bottom; + DestRect->bottom = Exchange; + } + + if (NULL != DestObj && STYPE_BITMAP != DestObj->iType && + (NULL == DestObj->pvScan0 || 0 == DestObj->lDelta)) + { + EnterLeave->DestGDI = (SURFGDI*)AccessInternalObjectFromUserObject(DestObj); + /* Driver needs to support DrvCopyBits, else we can't do anything */ + if (NULL == EnterLeave->DestGDI->CopyBits) + { + return FALSE; + } + + /* Allocate a temporary bitmap */ + BitmapSize.cx = DestRect->right - DestRect->left; + BitmapSize.cy = DestRect->bottom - DestRect->top; + Width = DIB_GetDIBWidthBytes(BitmapSize.cx, BitsPerFormat(DestObj->iBitmapFormat)); + EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width, + DestObj->iBitmapFormat, + BMF_NOZEROINIT, NULL); + *OutputObj = (SURFOBJ *) AccessUserObject((ULONG) EnterLeave->OutputBitmap); + + EnterLeave->DestRect.left = 0; + EnterLeave->DestRect.top = 0; + EnterLeave->DestRect.right = BitmapSize.cx; + EnterLeave->DestRect.bottom = BitmapSize.cy; + SrcPoint.x = DestRect->left; + SrcPoint.y = DestRect->top; + EnterLeave->TrivialClipObj = EngCreateClip(); + EnterLeave->TrivialClipObj->iDComplexity = DC_TRIVIAL; + if (! EnterLeave->DestGDI->CopyBits(*OutputObj, DestObj, + EnterLeave->TrivialClipObj, NULL, + &EnterLeave->DestRect, &SrcPoint)) + { + EngDeleteClip(EnterLeave->TrivialClipObj); + EngFreeMem((*OutputObj)->pvBits); + EngDeleteSurface(EnterLeave->OutputBitmap); + return FALSE; + } + EnterLeave->DestRect.left = DestRect->left; + EnterLeave->DestRect.top = DestRect->top; + EnterLeave->DestRect.right = DestRect->right; + EnterLeave->DestRect.bottom = DestRect->bottom; + Translate->x = - DestRect->left; + Translate->y = - DestRect->top; + } + else + { + Translate->x = 0; + Translate->y = 0; + *OutputObj = DestObj; + } + + EnterLeave->DestObj = DestObj; + EnterLeave->OutputObj = *OutputObj; + EnterLeave->ReadOnly = ReadOnly; + + return TRUE; +} + +BOOL STDCALL +IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave) +{ + POINTL SrcPoint; + BOOL Result; + + if (EnterLeave->OutputObj != EnterLeave->DestObj && NULL != EnterLeave->OutputObj) + { + if (! EnterLeave->ReadOnly) + { + SrcPoint.x = 0; + SrcPoint.y = 0; + Result = EnterLeave->DestGDI->CopyBits(EnterLeave->DestObj, + EnterLeave->OutputObj, + EnterLeave->TrivialClipObj, NULL, + &EnterLeave->DestRect, &SrcPoint); + } + EngFreeMem(EnterLeave->OutputObj->pvBits); + EngDeleteSurface(EnterLeave->OutputBitmap); + EngDeleteClip(EnterLeave->TrivialClipObj); + } + else + { + Result = TRUE; + } + + return Result; +} \ No newline at end of file diff --git a/reactos/subsys/win32k/eng/misc.h b/reactos/subsys/win32k/eng/misc.h new file mode 100644 index 00000000000..9177784c7ef --- /dev/null +++ b/reactos/subsys/win32k/eng/misc.h @@ -0,0 +1,28 @@ +#ifndef __ENG_MISC_H +#define __ENG_MISC_H + +#ifndef __ENG_OBJECTS_H +#include "objects.h" +#endif + +typedef struct INTENG_ENTER_LEAVE_TAG + { + /* Contents is private to EngEnter/EngLeave */ + SURFOBJ *DestObj; + SURFGDI *DestGDI; + SURFOBJ *OutputObj; + HBITMAP OutputBitmap; + CLIPOBJ *TrivialClipObj; + RECTL DestRect; + BOOL ReadOnly; + } INTENG_ENTER_LEAVE, *PINTENG_ENTER_LEAVE; + +extern BOOL STDCALL IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, + SURFOBJ *DestObj, + RECTL *DestRect, + BOOL ReadOnly, + POINTL *Translate, + SURFOBJ **OutputObj); +extern BOOL STDCALL IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave); + +#endif diff --git a/reactos/subsys/win32k/eng/surface.c b/reactos/subsys/win32k/eng/surface.c index cba32dbfc55..21830a2cd97 100644 --- a/reactos/subsys/win32k/eng/surface.c +++ b/reactos/subsys/win32k/eng/surface.c @@ -134,6 +134,7 @@ EngCreateBitmap(IN SIZEL Size, SurfObj->sizlBitmap = Size; SurfObj->iBitmapFormat = Format; SurfObj->iType = STYPE_BITMAP; + SurfObj->pvScan0 = SurfObj->pvBits; // Use flags to determine bitmap type -- TOP_DOWN or whatever diff --git a/reactos/subsys/win32k/include/inteng.h b/reactos/subsys/win32k/include/inteng.h index 9580fdf8368..02667461d8c 100644 --- a/reactos/subsys/win32k/include/inteng.h +++ b/reactos/subsys/win32k/include/inteng.h @@ -12,5 +12,16 @@ extern BOOL STDCALL IntEngLineTo(SURFOBJ *Surface, LONG y2, RECTL *RectBounds, MIX mix); +BOOL STDCALL IntEngBitBlt(SURFOBJ *DestObj, + SURFOBJ *SourceObj, + SURFOBJ *Mask, + CLIPOBJ *ClipRegion, + XLATEOBJ *ColorTranslation, + RECTL *DestRect, + POINTL *SourcePoint, + POINTL *MaskOrigin, + BRUSHOBJ *Brush, + POINTL *BrushOrigin, + ROP4 rop4); #endif diff --git a/reactos/subsys/win32k/makefile b/reactos/subsys/win32k/makefile index 2570c8a8633..5f2d38720d7 100644 --- a/reactos/subsys/win32k/makefile +++ b/reactos/subsys/win32k/makefile @@ -1,8 +1,8 @@ -# $Id: makefile,v 1.55 2003/02/15 19:16:33 gvg Exp $ +# $Id: makefile,v 1.56 2003/02/25 23:08:52 gvg Exp $ PATH_TO_TOP = ../.. -TARGET_TYPE = export_driver +TARGET_TYPE = subsystem TARGET_NAME = win32k @@ -22,7 +22,8 @@ TARGET_CFLAGS = $(CFLAGS_DBG) -I$(PATH_TO_TOP)/ntoskrnl/include -DUNICODE -Wall ENG_OBJECTS= eng/debug.o eng/mem.o eng/brush.o eng/bitblt.o eng/clip.o \ eng/copybits.o eng/device.o eng/handle.o eng/lineto.o eng/paint.o \ - eng/palette.o eng/surface.o eng/xlate.o eng/transblt.o eng/mouse.o + eng/palette.o eng/surface.o eng/xlate.o eng/transblt.o eng/mouse.o \ + eng/misc.o MAIN_OBJECTS = main/dllmain.o main/svctabm.o MISC_OBJECTS = misc/driver.o misc/error.o misc/math.o misc/object.o LDR_OBJECTS = ldr/loader.o diff --git a/reactos/subsys/win32k/misc/driver.c b/reactos/subsys/win32k/misc/driver.c index 526e4df46d7..adb9f4bee7b 100644 --- a/reactos/subsys/win32k/misc/driver.c +++ b/reactos/subsys/win32k/misc/driver.c @@ -1,4 +1,4 @@ -/* $Id: driver.c,v 1.22 2002/09/08 10:23:51 chorns Exp $ +/* $Id: driver.c,v 1.23 2003/02/25 23:08:53 gvg Exp $ * * GDI Driver support routines * (mostly swiped from Wine) @@ -12,13 +12,14 @@ #include #include #include -//#include "../../ntoskrnl/include/internal/module.h" #include #include #define NDEBUG #include +#define DRIVER_TAG TAG('G', 'D', 'R', 'V') + typedef struct _GRAPHICS_DRIVER { PWSTR Name; @@ -32,14 +33,16 @@ static PGRAPHICS_DRIVER GenericDriver = 0; BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver) { - PGRAPHICS_DRIVER Driver = ExAllocatePool(NonPagedPool, sizeof(*Driver)); + PGRAPHICS_DRIVER Driver = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Driver), DRIVER_TAG); DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name ); if (!Driver) return FALSE; Driver->ReferenceCount = 0; Driver->EnableDriver = EnableDriver; if (Name) { - Driver->Name = ExAllocatePool(PagedPool, (wcslen(Name) + 1) * sizeof(WCHAR)); + Driver->Name = ExAllocatePoolWithTag(PagedPool, + (wcslen(Name) + 1) * sizeof(WCHAR), + DRIVER_TAG); wcscpy(Driver->Name, Name); Driver->Next = DriverList; DriverList = Driver; @@ -56,16 +59,69 @@ BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver) return TRUE; } -PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name) +PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name) { + static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\"; + static WCHAR DefaultExtension[] = L".DLL"; SYSTEM_LOAD_IMAGE GdiDriverInfo; GRAPHICS_DRIVER *Driver = DriverList; NTSTATUS Status; + WCHAR *FullName; + WCHAR *p; + BOOL PathSeparatorFound; + BOOL DotFound; + UINT Size; + + DotFound = FALSE; + PathSeparatorFound = FALSE; + p = Name; + while (L'\0' != *p) + { + if (L'\\' == *p || L'/' == *p) + { + PathSeparatorFound = TRUE; + DotFound = FALSE; + } + else if (L'.' == *p) + { + DotFound = TRUE; + } + p++; + } + + Size = (wcslen(Name) + 1) * sizeof(WCHAR); + if (! PathSeparatorFound) + { + Size += sizeof(DefaultPath) - sizeof(WCHAR); + } + if (! DotFound) + { + Size += sizeof(DefaultExtension) - sizeof(WCHAR); + } + FullName = ExAllocatePoolWithTag(PagedPool, Size, DRIVER_TAG); + if (NULL == FullName) + { + DPRINT1("Out of memory\n"); + return NULL; + } + if (PathSeparatorFound) + { + FullName[0] = L'\0'; + } + else + { + wcscpy(FullName, DefaultPath); + } + wcscat(FullName, Name); + if (! DotFound) + { + wcscat(FullName, DefaultExtension); + } /* First see if the driver hasn't already been loaded */ - while (Driver && Name) + while (Driver && FullName) { - if (!_wcsicmp( Driver->Name, Name)) + if (!_wcsicmp( Driver->Name, FullName)) { return Driver->EnableDriver; } @@ -73,8 +129,9 @@ PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name) } /* If not, then load it */ - RtlInitUnicodeString (&GdiDriverInfo.ModuleName, (LPWSTR)Name); + RtlInitUnicodeString (&GdiDriverInfo.ModuleName, (LPWSTR)FullName); Status = ZwSetSystemInformation (SystemLoadImage, &GdiDriverInfo, sizeof(SYSTEM_LOAD_IMAGE)); + ExFreePool(FullName); if (!NT_SUCCESS(Status)) return NULL; DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint); diff --git a/reactos/subsys/win32k/objects/bitmaps.c b/reactos/subsys/win32k/objects/bitmaps.c index f8d37caaae1..81615040c50 100644 --- a/reactos/subsys/win32k/objects/bitmaps.c +++ b/reactos/subsys/win32k/objects/bitmaps.c @@ -4,6 +4,7 @@ #include //#include #include "../eng/handle.h" +#include #define NDEBUG #include @@ -86,7 +87,7 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest, // Perform the bitblt operation - Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, ROP); + Status = IntEngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, ROP); if(SurfDestAlloc == TRUE) ExFreePool(SurfDest); if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc); diff --git a/reactos/subsys/win32k/objects/brush.c b/reactos/subsys/win32k/objects/brush.c index 00fd50f2c15..01e2f89e48d 100644 --- a/reactos/subsys/win32k/objects/brush.c +++ b/reactos/subsys/win32k/objects/brush.c @@ -1,4 +1,4 @@ -/* $Id: brush.c,v 1.18 2003/01/18 20:46:31 ei Exp $ +/* $Id: brush.c,v 1.19 2003/02/25 23:08:54 gvg Exp $ */ @@ -9,6 +9,7 @@ #include //#include #include +#include #define NDEBUG #include @@ -221,17 +222,17 @@ BOOL STDCALL W32kPatBlt(HDC hDC, DestRect.top = YLeft + Height + dc->w.DCOrgY; DestRect.bottom = YLeft + dc->w.DCOrgY; } - ret = EngBitBlt(SurfObj, - NULL, - NULL, - NULL, - NULL, - &DestRect, - NULL, - NULL, - BrushObj, - NULL, - PATCOPY); + ret = IntEngBitBlt(SurfObj, + NULL, + NULL, + NULL, + NULL, + &DestRect, + NULL, + NULL, + BrushObj, + NULL, + PATCOPY); } GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC ); DC_ReleasePtr( hDC ); diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 22b5317a5a8..d73188d8c8d 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -1,4 +1,4 @@ -/* $Id: dc.c,v 1.46 2003/02/15 19:16:34 gvg Exp $ +/* $Id: dc.c,v 1.47 2003/02/25 23:08:54 gvg Exp $ * * DC.C - Device context functions * @@ -184,13 +184,61 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC) return hNewDC; } +static BOOL STDCALL FindDriverFileNames(PUNICODE_STRING DriverFileNames) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + UNICODE_STRING RegistryPath; + NTSTATUS Status; + + RtlInitUnicodeString(&RegistryPath, NULL); + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].Name = L"\\Device\\Video0"; + QueryTable[0].EntryContext = &RegistryPath; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP, + L"VIDEO", + QueryTable, + NULL, + NULL); + if (! NT_SUCCESS(Status)) + { + DPRINT1("No \\Device\\Video0 value in DEVICEMAP\\VIDEO found\n"); + return FALSE; + } + + DPRINT("RegistryPath %S\n", RegistryPath.Buffer); + + QueryTable[0].Name = L"InstalledDisplayDrivers"; + QueryTable[0].EntryContext = DriverFileNames; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + RegistryPath.Buffer, + QueryTable, + NULL, + NULL); + RtlFreeUnicodeString(&RegistryPath); + if (! NT_SUCCESS(Status)) + { + DPRINT1("No InstalledDisplayDrivers value in service entry found\n"); + return FALSE; + } + + DPRINT("DriverFileNames %S\n", DriverFileNames->Buffer); + + return TRUE; +} + BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver, LPCWSTR Device) { - PGD_ENABLEDRIVER GDEnableDriver; + PGD_ENABLEDRIVER GDEnableDriver; HANDLE DeviceDriver; - DRVENABLEDATA DED; + DRVENABLEDATA DED; PSURFOBJ SurfObj; + UNICODE_STRING DriverFileNames; + PWSTR CurrentName; + BOOL GotDriver; /* Open the miniport driver */ if ((DeviceDriver = DRIVER_FindMPDriver(Driver)) == NULL) @@ -199,22 +247,64 @@ BOOL STDCALL W32kCreatePrimarySurface(LPCWSTR Driver, return(FALSE); } - /* Get the DDI driver's entry point */ - /* FIXME: Retrieve DDI driver name from registry */ - if ((GDEnableDriver = DRIVER_FindDDIDriver(L"\\SystemRoot\\system32\\drivers\\vgaddi.dll")) == NULL) + /* Retrieve DDI driver names from registry */ + RtlInitUnicodeString(&DriverFileNames, NULL); + if (! FindDriverFileNames(&DriverFileNames)) { - DPRINT("FindDDIDriver failed\n"); + DPRINT("FindDriverFileNames failed\n"); return(FALSE); } - /* Call DDI driver's EnableDriver function */ - RtlZeroMemory(&DED, sizeof(DED)); - - if (!GDEnableDriver(DDI_DRIVER_VERSION, sizeof(DED), &DED)) + /* DriverFileNames may be a list of drivers in REG_SZ_MULTI format, scan all of + them until a good one found */ + CurrentName = DriverFileNames.Buffer; + GotDriver = FALSE; + while (! GotDriver && CurrentName < DriverFileNames.Buffer + DriverFileNames.Length) { - DPRINT("DrvEnableDriver failed\n"); - return(FALSE); + /* Get the DDI driver's entry point */ + GDEnableDriver = DRIVER_FindDDIDriver(CurrentName); + if (NULL == GDEnableDriver) + { + DPRINT("FindDDIDriver failed for %S\n", CurrentName); + } + else + { + /* Call DDI driver's EnableDriver function */ + RtlZeroMemory(&DED, sizeof(DED)); + + if (!GDEnableDriver(DDI_DRIVER_VERSION, sizeof(DED), &DED)) + { + DPRINT("DrvEnableDriver failed for %S\n", CurrentName); + } + else + { + GotDriver = TRUE; + } + } + + if (! GotDriver) + { + /* Skip to the next name but never get past the Unicode string */ + while (L'\0' != *CurrentName && + CurrentName < DriverFileNames.Buffer + DriverFileNames.Length) + { + CurrentName++; + } + if (CurrentName < DriverFileNames.Buffer + DriverFileNames.Length) + { + CurrentName++; + } + } } + RtlFreeUnicodeString(&DriverFileNames); + if (! GotDriver) + { + DPRINT("No suitable driver found\n"); + return FALSE; + } + + DPRINT("Display driver %S loaded\n", DriverName); + DPRINT("Building DDI Functions\n"); /* Construct DDI driver function dispatch table */ @@ -338,7 +428,8 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver, DPRINT("Bits per pel: %u\n", NewDC->w.bitsPerPixel); - NewDC->w.hVisRgn = W32kCreateRectRgn(0, 0, 640, 480); + NewDC->w.hVisRgn = W32kCreateRectRgn(0, 0, SurfGDI->SurfObj.sizlBitmap.cx, + SurfGDI->SurfObj.sizlBitmap.cy); DC_ReleasePtr( hNewDC ); /* Initialize the DC state */ diff --git a/reactos/subsys/win32k/objects/text.c b/reactos/subsys/win32k/objects/text.c index ded81fde906..ae59128fb0d 100644 --- a/reactos/subsys/win32k/objects/text.c +++ b/reactos/subsys/win32k/objects/text.c @@ -10,6 +10,8 @@ #include "../eng/handle.h" +#include + // #define NDEBUG #include @@ -713,8 +715,8 @@ W32kTextOut(HDC hDC, DestRect.top = TextTop + yoff - glyph->bitmap_top; DestRect.right = TextLeft + glyph->bitmap.width; DestRect.bottom = DestRect.top + glyph->bitmap.rows; - bitSize.cx = pitch-1; - bitSize.cy = glyph->bitmap.rows-1; + bitSize.cx = pitch; + bitSize.cy = glyph->bitmap.rows; MaskRect.right = glyph->bitmap.width; MaskRect.bottom = glyph->bitmap.rows; @@ -725,7 +727,7 @@ W32kTextOut(HDC hDC, SourceGlyphSurf = (PSURFOBJ)AccessUserObject(HSourceGlyph); // Use the font data as a mask to paint onto the DCs surface using a brush - EngBitBlt(SurfObj, NULL, SourceGlyphSurf, NULL, NULL, &DestRect, &SourcePoint, &MaskRect, Brush, &BrushOrigin, 0xAACC); + IntEngBitBlt(SurfObj, NULL, SourceGlyphSurf, NULL, NULL, &DestRect, &SourcePoint, &MaskRect, Brush, &BrushOrigin, 0xAACC); EngDeleteSurface(HSourceGlyph); diff --git a/reactos/system.hiv b/reactos/system.hiv index d1d5648fc1a..cd18ac167b9 100644 --- a/reactos/system.hiv +++ b/reactos/system.hiv @@ -290,6 +290,18 @@ REGEDIT4 "Start"=dword:00000001 "Type"=dword:00000001 +[\Registry\Machine\SYSTEM\ControlSet001\Services\Vga\Device0] +"InstalledDisplayDrivers"=multi:"vgaddi" +[\Registry\Machine\SYSTEM\ControlSet001\Services\vmx_svga] +"ErrorControl"=dword:00000000 +"Group"="Video" +"ImagePath"=expand:"system32\drivers\vmx_svga.sys" +"Start"=dword:00000004 +"Type"=dword:00000001 + +[\Registry\Machine\SYSTEM\ControlSet001\Services\vmx_svga\Device0] +"InstalledDisplayDrivers"=multi:"vmx_fb" + [\Registry\Machine\SYSTEM\ControlSet002] [\Registry\Machine\SYSTEM\Select] diff --git a/reactos/tools/helper.mk b/reactos/tools/helper.mk index 528a8963dc3..95a51e7df0c 100644 --- a/reactos/tools/helper.mk +++ b/reactos/tools/helper.mk @@ -1,4 +1,4 @@ -# $Id: helper.mk,v 1.26 2003/01/15 20:18:12 chorns Exp $ +# $Id: helper.mk,v 1.27 2003/02/25 23:08:54 gvg Exp $ # # Helper makefile for ReactOS modules # Variables this makefile accepts: @@ -14,6 +14,7 @@ # bootpgm = Boot program # miniport = Kernel mode driver that does not link with ntoskrnl.exe or hal.dll # gdi_driver = Kernel mode graphics driver that link with win32k.sys +# subsystem = Kernel subsystem # $TARGET_APPTYPE = Application type (windows,native,console) # $TARGET_NAME = Base name of output file and .rc, .def, and .edf files # $TARGET_OBJECTS = Object files that compose the module @@ -275,7 +276,7 @@ ifeq ($(TARGET_TYPE),gdi_driver) MK_IMPLIBONLY := no MK_IMPLIBDEFPATH := $(DDK_PATH_LIB) MK_IMPLIB_EXT := .a - MK_INSTALLDIR := system32/drivers + MK_INSTALLDIR := system32 MK_DISTDIR := drivers MK_RES_BASE := $(TARGET_NAME) endif @@ -321,6 +322,25 @@ ifeq ($(TARGET_TYPE),proglib) endif endif +ifeq ($(TARGET_TYPE),subsystem) + MK_MODE := kernel + MK_EXETYPE := dll + MK_DEFEXT := .sys + MK_DEFENTRY := _DriverEntry@8 + MK_DDKLIBS := ntoskrnl.a hal.a + MK_SDKLIBS := + MK_CFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC) + MK_CPPFLAGS := -D__NTDRIVER__ -I./ -I$(DDK_PATH_INC) + MK_RCFLAGS := --include-dir $(SDK_PATH_INC) + MK_IMPLIB := yes + MK_IMPLIBONLY := no + MK_IMPLIBDEFPATH := $(DDK_PATH_LIB) + MK_IMPLIB_EXT := .a + MK_INSTALLDIR := system32 + MK_DISTDIR := drivers + MK_RES_BASE := $(TARGET_NAME) +endif + MK_RESOURCE := $(MK_RES_BASE).coff diff --git a/reactos/txtsetup.sif b/reactos/txtsetup.sif index d31550402b1..4686db13ac9 100644 --- a/reactos/txtsetup.sif +++ b/reactos/txtsetup.sif @@ -22,7 +22,7 @@ blue.sys = 3 floppy.sys = 3 null.sys = 3 serial.sys = 3 -vgaddi.dll = 3 +vgaddi.dll = 2 vgamp.sys = 3 videoprt.sys = 3 @@ -87,7 +87,7 @@ services.exe = 2 shell.exe = 2 winlogon.exe = 2 -win32k.sys = 3 +win32k.sys = 2 helb____.ttf = 6 timr____.ttf = 6