mirror of
https://github.com/reactos/reactos.git
synced 2024-09-27 21:16:34 +00:00
Miniport driver now loaded from win32k
Display and miniport drivers can now talk to each other Sets the VGA video mode svn path=/trunk/; revision=1067
This commit is contained in:
parent
40ee84e997
commit
e1d6086025
|
@ -1,16 +1,14 @@
|
|||
/*
|
||||
* entry.c
|
||||
*
|
||||
* $Revision: 1.1 $
|
||||
* $Revision: 1.2 $
|
||||
* $Author: jfilby $
|
||||
* $Date: 2000/03/10 12:45:45 $
|
||||
* $Date: 2000/03/17 21:02:57 $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/winddi.h>
|
||||
#include "gdiinfo.h"
|
||||
#include <internal/debug.h>
|
||||
#include "vgaddi.h"
|
||||
|
||||
#define DBG_PREFIX "VGADDI: "
|
||||
|
||||
|
@ -45,7 +43,7 @@ DRVFN FuncList[] =
|
|||
{INDEX_DrvDisableSurface, (PFN) VGADDIDisableSurface},
|
||||
{INDEX_DrvEnablePDEV, (PFN) VGADDIEnablePDEV},
|
||||
{INDEX_DrvEnableSurface, (PFN) VGADDIEnableSurface},
|
||||
{INDEX_DrvGetModes, (PFN) VGADDIGetModes}
|
||||
{INDEX_DrvGetModes, (PFN) VGADDIGetModes},
|
||||
|
||||
#if 0
|
||||
/* Optional Display driver functions */
|
||||
|
@ -85,10 +83,10 @@ DrvEnableDriver(IN ULONG EngineVersion,
|
|||
IN ULONG SizeOfDED,
|
||||
OUT PDRVENABLEDATA DriveEnableData)
|
||||
{
|
||||
DbgPrint("VGADDI: DrvEnableDriver called...\n");
|
||||
EngDebugPrint("VGADDI", "DrvEnableDriver called...\n", 0);
|
||||
|
||||
DriveEnableData->pdrvfn = FuncList;
|
||||
DriveEnableData->c = sizeof FuncList / sizeof &FuncList[0];
|
||||
DriveEnableData->c = sizeof(FuncList) / sizeof(DRVFN);
|
||||
DriveEnableData->iDriverVersion = DDI_DRIVER_VERSION;
|
||||
|
||||
return TRUE;
|
||||
|
@ -144,9 +142,7 @@ DHPDEV VGADDIEnablePDEV(IN DEVMODEW *DM,
|
|||
{
|
||||
PPDEV PDev;
|
||||
|
||||
DbgPrint("Welcome to VGADDIEnablePDEV!!\n");
|
||||
PDev = EngAllocMem(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG);
|
||||
DbgPrint("Engallocmem worked?!\n");
|
||||
if (PDev == NULL)
|
||||
{
|
||||
EngDebugPrint(DBG_PREFIX, "EngAllocMem failed for PDEV\n", 0);
|
||||
|
@ -154,9 +150,19 @@ DbgPrint("Engallocmem worked?!\n");
|
|||
return NULL;
|
||||
}
|
||||
PDev->KMDriver = Driver;
|
||||
PDev->xyCursor.x = 320;
|
||||
PDev->xyCursor.y = 240;
|
||||
PDev->ptlExtent.x = 0;
|
||||
PDev->ptlExtent.y = 0;
|
||||
PDev->cExtent = 0;
|
||||
PDev->flCursor = CURSOR_DOWN;
|
||||
// FIXME: fill out DevCaps
|
||||
// FIXME: full out DevInfo
|
||||
|
||||
/* FIXME: fill out DevCaps */
|
||||
/* FIXME: full out DevInfo */
|
||||
devinfoVGA.hpalDefault = EngCreatePalette(PAL_INDEXED, 16,
|
||||
(PULONG)(VGApalette.PaletteEntry), 0, 0, 0);
|
||||
|
||||
*DI = devinfoVGA;
|
||||
|
||||
return PDev;
|
||||
}
|
||||
|
@ -176,30 +182,284 @@ VOID VGADDICompletePDEV(IN DHPDEV PDev,
|
|||
VOID VGADDIAssertMode(IN DHPDEV DPev,
|
||||
IN BOOL Enable)
|
||||
{
|
||||
DbgPrint("Yeeha!!\n");
|
||||
EngDebugPrint(DBG_PREFIX, "UNIMPLEMENTED\n", 0);
|
||||
PPDEV ppdev = (PPDEV)DPev;
|
||||
ULONG returnedDataLength;
|
||||
|
||||
if(Enable==TRUE)
|
||||
{
|
||||
// Reenable our graphics mode
|
||||
|
||||
/* if (!InitPointer(ppdev))
|
||||
{
|
||||
// Failed to set pointer
|
||||
return FALSE;
|
||||
} POINTER CODE CURRENTLY UNIMPLEMENTED... */
|
||||
|
||||
if (!InitVGA(ppdev, FALSE))
|
||||
{
|
||||
// Failed to initialize the VGA
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Go back to last known mode
|
||||
|
||||
if (EngDeviceIoControl(ppdev->KMDriver,
|
||||
IOCTL_VIDEO_RESET_DEVICE,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
&returnedDataLength))
|
||||
{
|
||||
// Failed to go back to mode
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
VOID VGADDIDisablePDEV(IN DHPDEV PDev)
|
||||
{
|
||||
EngDebugPrint(DBG_PREFIX, "UNIMPLEMENTED\n", 0);
|
||||
PPDEV ppdev = (PPDEV)PDev;
|
||||
|
||||
EngDeletePalette(devinfoVGA.hpalDefault);
|
||||
|
||||
if (ppdev->pjPreallocSSBBuffer != NULL)
|
||||
{
|
||||
EngFreeMem(ppdev->pjPreallocSSBBuffer);
|
||||
}
|
||||
|
||||
if (ppdev->pucDIB4ToVGAConvBuffer != NULL)
|
||||
{
|
||||
EngFreeMem(ppdev->pucDIB4ToVGAConvBuffer);
|
||||
}
|
||||
|
||||
EngFreeMem(PDev);
|
||||
}
|
||||
|
||||
VOID VGADDIDisableSurface(IN DHPDEV PDev)
|
||||
{
|
||||
EngDebugPrint(DBG_PREFIX, "UNIMPLEMENTED\n", 0);
|
||||
PPDEV ppdev = (PPDEV)PDev;
|
||||
PDEVSURF pdsurf = ppdev->AssociatedSurf;
|
||||
PSAVED_SCREEN_BITS pSSB, pSSBNext;
|
||||
|
||||
EngFreeMem(pdsurf->BankSelectInfo);
|
||||
|
||||
if (pdsurf->BankInfo != NULL) {
|
||||
EngFreeMem(pdsurf->BankInfo);
|
||||
}
|
||||
if (pdsurf->BankInfo2RW != NULL) {
|
||||
EngFreeMem(pdsurf->BankInfo2RW);
|
||||
}
|
||||
if (pdsurf->BankBufferPlane0 != NULL) {
|
||||
EngFreeMem(pdsurf->BankBufferPlane0);
|
||||
}
|
||||
if (ppdev->PointerAttributes != NULL) {
|
||||
EngFreeMem(ppdev->PointerAttributes);
|
||||
}
|
||||
|
||||
// free any pending saved screen bit blocks
|
||||
pSSB = pdsurf->ssbList;
|
||||
while (pSSB != (PSAVED_SCREEN_BITS) NULL) {
|
||||
|
||||
// Point to the next saved screen bits block
|
||||
pSSBNext = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
|
||||
|
||||
// Free the current block
|
||||
EngFreeMem(pSSB);
|
||||
pSSB = pSSBNext;
|
||||
}
|
||||
|
||||
EngDeleteSurface((HSURF) ppdev->SurfHandle);
|
||||
EngFreeMem(pdsurf); // free the surface
|
||||
}
|
||||
|
||||
VOID InitSavedBits(PPDEV ppdev)
|
||||
{
|
||||
if (!(ppdev->fl & DRIVER_OFFSCREEN_REFRESHED))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// set up rect to right of visible screen
|
||||
ppdev->SavedBitsRight.left = ppdev->sizeSurf.cx;
|
||||
ppdev->SavedBitsRight.top = 0;
|
||||
ppdev->SavedBitsRight.right = ppdev->sizeMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
|
||||
ppdev->SavedBitsRight.bottom = ppdev->sizeSurf.cy;
|
||||
|
||||
if ((ppdev->SavedBitsRight.right <= ppdev->SavedBitsRight.left) ||
|
||||
(ppdev->SavedBitsRight.bottom <= ppdev->SavedBitsRight.top))
|
||||
{
|
||||
ppdev->SavedBitsRight.left = 0;
|
||||
ppdev->SavedBitsRight.top = 0;
|
||||
ppdev->SavedBitsRight.right = 0;
|
||||
ppdev->SavedBitsRight.bottom = 0;
|
||||
}
|
||||
|
||||
// set up rect below visible screen
|
||||
ppdev->SavedBitsBottom.left = 0;
|
||||
ppdev->SavedBitsBottom.top = ppdev->sizeSurf.cy;
|
||||
ppdev->SavedBitsBottom.right = ppdev->sizeMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
|
||||
ppdev->SavedBitsBottom.bottom = ppdev->sizeMem.cy - ppdev->NumScansUsedByPointer;
|
||||
|
||||
if ((ppdev->SavedBitsBottom.right <= ppdev->SavedBitsBottom.left) ||
|
||||
(ppdev->SavedBitsBottom.bottom <= ppdev->SavedBitsBottom.top))
|
||||
{
|
||||
ppdev->SavedBitsBottom.left = 0;
|
||||
ppdev->SavedBitsBottom.top = 0;
|
||||
ppdev->SavedBitsBottom.right = 0;
|
||||
ppdev->SavedBitsBottom.bottom = 0;
|
||||
}
|
||||
|
||||
ppdev->BitsSaved = FALSE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HSURF VGADDIEnableSurface(IN DHPDEV PDev)
|
||||
{
|
||||
EngDebugPrint(DBG_PREFIX, "UNIMPLEMENTED\n", 0);
|
||||
PPDEV ppdev = (PPDEV)PDev;
|
||||
PDEVSURF pdsurf;
|
||||
DHSURF dhsurf;
|
||||
HSURF hsurf;
|
||||
|
||||
// Initialize the VGA
|
||||
if (!InitVGA(ppdev, TRUE))
|
||||
{
|
||||
goto error_done;
|
||||
}
|
||||
|
||||
dhsurf = (DHSURF)EngAllocMem(0, sizeof(DEVSURF), ALLOC_TAG);
|
||||
if (dhsurf == (DHSURF) 0)
|
||||
{
|
||||
goto error_done;
|
||||
}
|
||||
|
||||
pdsurf = (PDEVSURF) dhsurf;
|
||||
pdsurf->ident = DEVSURF_IDENT;
|
||||
pdsurf->flSurf = 0;
|
||||
pdsurf->Format = BMF_PHYSDEVICE;
|
||||
pdsurf->jReserved1 = 0;
|
||||
pdsurf->jReserved2 = 0;
|
||||
pdsurf->ppdev = ppdev;
|
||||
pdsurf->sizeSurf.cx = ppdev->sizeSurf.cx;
|
||||
pdsurf->sizeSurf.cy = ppdev->sizeSurf.cy;
|
||||
pdsurf->NextPlane = 0;
|
||||
pdsurf->Scan0 = ppdev->fbScreen;
|
||||
pdsurf->BitmapStart = ppdev->fbScreen;
|
||||
pdsurf->StartBmp = ppdev->fbScreen;
|
||||
/* pdsurf->Conv = &ConvertBuffer[0]; */
|
||||
|
||||
/* if (!bInitPointer(ppdev)) {
|
||||
DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n"));
|
||||
goto error_clean;
|
||||
} POINTER CODE UNIMPLEMENTED */
|
||||
|
||||
/* if (!SetUpBanking(pdsurf, ppdev)) {
|
||||
DISPDBG((0, "DrvEnablePDEV failed SetUpBanking\n"));
|
||||
goto error_clean;
|
||||
} BANKING CODE UNIMPLEMENTED */
|
||||
|
||||
if ((hsurf = EngCreateDeviceSurface(dhsurf, ppdev->sizeSurf, BMF_4BPP)) ==
|
||||
(HSURF)0)
|
||||
{
|
||||
// Call to EngCreateDeviceSurface failed
|
||||
EngDebugPrint("VGADDI:", "EngCreateDeviceSurface call failed\n", 0);
|
||||
goto error_clean;
|
||||
}
|
||||
|
||||
InitSavedBits(ppdev);
|
||||
|
||||
if (EngAssociateSurface(hsurf, ppdev->GDIDevHandle, HOOK_BITBLT | HOOK_PAINT | HOOK_LINETO))
|
||||
{
|
||||
EngDebugPrint("VGADDI:", "Successfully associated surface\n", 0);
|
||||
ppdev->SurfHandle = hsurf;
|
||||
ppdev->AssociatedSurf = pdsurf;
|
||||
|
||||
// Set up an empty saved screen block list
|
||||
pdsurf->ssbList = NULL;
|
||||
|
||||
return(hsurf);
|
||||
}
|
||||
|
||||
EngDeleteSurface(hsurf);
|
||||
|
||||
error_clean:
|
||||
EngFreeMem(dhsurf);
|
||||
|
||||
error_done:
|
||||
return((HSURF)0);
|
||||
}
|
||||
|
||||
ULONG VGADDIGetModes(IN HANDLE Driver,
|
||||
IN ULONG DataSize,
|
||||
OUT PDEVMODEW DM)
|
||||
{
|
||||
EngDebugPrint(DBG_PREFIX, "UNIMPLEMENTED\n", 0);
|
||||
DWORD NumModes;
|
||||
DWORD ModeSize;
|
||||
DWORD OutputSize;
|
||||
DWORD OutputModes = DataSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
|
||||
PVIDEO_MODE_INFORMATION VideoModeInformation, VideoTemp;
|
||||
|
||||
NumModes = getAvailableModes(Driver,
|
||||
(PVIDEO_MODE_INFORMATION *) &VideoModeInformation,
|
||||
&ModeSize);
|
||||
|
||||
if (NumModes == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (DM == NULL)
|
||||
{
|
||||
OutputSize = NumModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
|
||||
} else {
|
||||
|
||||
OutputSize=0;
|
||||
VideoTemp = VideoModeInformation;
|
||||
|
||||
do
|
||||
{
|
||||
if (VideoTemp->Length != 0)
|
||||
{
|
||||
if (OutputModes == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
memset(DM, 0, sizeof(DEVMODEW));
|
||||
memcpy(DM->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
|
||||
|
||||
DM->dmSpecVersion = DM_SPECVERSION;
|
||||
DM->dmDriverVersion = DM_SPECVERSION;
|
||||
DM->dmSize = sizeof(DEVMODEW);
|
||||
DM->dmDriverExtra = DRIVER_EXTRA_SIZE;
|
||||
DM->dmBitsPerPel = VideoTemp->NumberOfPlanes *
|
||||
VideoTemp->BitsPerPlane;
|
||||
DM->dmPelsWidth = VideoTemp->VisScreenWidth;
|
||||
DM->dmPelsHeight = VideoTemp->VisScreenHeight;
|
||||
DM->dmDisplayFrequency = VideoTemp->Frequency;
|
||||
DM->dmDisplayFlags = 0;
|
||||
|
||||
DM->dmFields = DM_BITSPERPEL |
|
||||
DM_PELSWIDTH |
|
||||
DM_PELSHEIGHT |
|
||||
DM_DISPLAYFREQUENCY |
|
||||
DM_DISPLAYFLAGS ;
|
||||
|
||||
// next DEVMODE entry
|
||||
OutputModes--;
|
||||
|
||||
DM = (PDEVMODEW) ( ((ULONG)DM) + sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
|
||||
|
||||
OutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
|
||||
}
|
||||
|
||||
VideoTemp = (PVIDEO_MODE_INFORMATION)(((PUCHAR)VideoTemp) + ModeSize);
|
||||
|
||||
} while (--NumModes);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
123
reactos/drivers/dd/vga/display/main/gdiinfo.h
Normal file
123
reactos/drivers/dd/vga/display/main/gdiinfo.h
Normal file
|
@ -0,0 +1,123 @@
|
|||
#include "..\vgaddi.h"
|
||||
|
||||
GDIINFO gaulCap = {
|
||||
GDI_DRIVER_VERSION,
|
||||
DT_RASDISPLAY, // ulTechnology
|
||||
0, // ulHorzSize
|
||||
0, // ulVertSize
|
||||
0, // ulHorzRes (filled in at initialization)
|
||||
0, // ulVertRes (filled in at initialization)
|
||||
4, // cBitsPixel
|
||||
1, // cPlanes
|
||||
16, // ulNumColors
|
||||
0, // flRaster (DDI reserved field)
|
||||
|
||||
0, // ulLogPixelsX (filled in at initialization)
|
||||
0, // ulLogPixelsY (filled in at initialization)
|
||||
|
||||
TC_RA_ABLE | TC_SCROLLBLT, // flTextCaps
|
||||
|
||||
6, // ulDACRed
|
||||
6, // ulDACGree
|
||||
6, // ulDACBlue
|
||||
|
||||
0x0024, // ulAspectX (one-to-one aspect ratio)
|
||||
0x0024, // ulAspectY
|
||||
0x0033, // ulAspectXY
|
||||
|
||||
1, // xStyleStep
|
||||
1, // yStyleSte;
|
||||
3, // denStyleStep
|
||||
|
||||
{ 0, 0 }, // ptlPhysOffset
|
||||
{ 0, 0 }, // szlPhysSize
|
||||
|
||||
0, // ulNumPalReg (win3.1 16 color drivers say 0 too)
|
||||
|
||||
// These fields are for halftone initialization.
|
||||
|
||||
{ // ciDevice, ColorInfo
|
||||
{ 6700, 3300, 0 }, // Red
|
||||
{ 2100, 7100, 0 }, // Green
|
||||
{ 1400, 800, 0 }, // Blue
|
||||
{ 1750, 3950, 0 }, // Cyan
|
||||
{ 4050, 2050, 0 }, // Magenta
|
||||
{ 4400, 5200, 0 }, // Yellow
|
||||
{ 3127, 3290, 0 }, // AlignmentWhite
|
||||
20000, // RedGamma
|
||||
20000, // GreenGamma
|
||||
20000, // BlueGamma
|
||||
0, 0, 0, 0, 0, 0
|
||||
},
|
||||
|
||||
0, // ulDevicePelsDPI
|
||||
PRIMARY_ORDER_CBA, // ulPrimaryOrder
|
||||
HT_PATSIZE_4x4_M, // ulHTPatternSize
|
||||
HT_FORMAT_4BPP_IRGB, // ulHTOutputFormat
|
||||
HT_FLAG_ADDITIVE_PRIMS, // flHTFlags
|
||||
|
||||
0, // ulVRefresh
|
||||
8, // ulBltAlignment
|
||||
0, // ulPanningHorzRes
|
||||
0, // ulPanningVertRes
|
||||
};
|
||||
|
||||
// Palette for VGA
|
||||
|
||||
typedef struct _VGALOGPALETTE
|
||||
{
|
||||
USHORT ident;
|
||||
USHORT NumEntries;
|
||||
PALETTEENTRY PaletteEntry[16];
|
||||
} VGALOGPALETTE;
|
||||
|
||||
const VGALOGPALETTE VGApalette =
|
||||
{
|
||||
|
||||
0x400, // driver version
|
||||
16, // num entries
|
||||
{
|
||||
{ 0, 0, 0, 0 }, // 0
|
||||
{ 0x80,0, 0, 0 }, // 1
|
||||
{ 0, 0x80,0, 0 }, // 2
|
||||
{ 0x80,0x80,0, 0 }, // 3
|
||||
{ 0, 0, 0x80,0 }, // 4
|
||||
{ 0x80,0, 0x80,0 }, // 5
|
||||
{ 0, 0x80,0x80,0 }, // 6
|
||||
{ 0x80,0x80,0x80,0 }, // 7
|
||||
|
||||
{ 0xC0,0xC0,0xC0,0 }, // 8
|
||||
{ 0xFF,0, 0, 0 }, // 9
|
||||
{ 0, 0xFF,0, 0 }, // 10
|
||||
{ 0xFF,0xFF,0, 0 }, // 11
|
||||
{ 0, 0, 0xFF,0 }, // 12
|
||||
{ 0xFF,0, 0xFF,0 }, // 13
|
||||
{ 0, 0xFF,0xFF,0 }, // 14
|
||||
{ 0xFF,0xFF,0xFF,0 } // 15
|
||||
}
|
||||
};
|
||||
|
||||
// Devinfo structure passed back to the engine in DrvEnablePDEV
|
||||
|
||||
// FIXME: The names of these fonts should be L"..." (For Unicode).. but that
|
||||
// just doesn't seem compatible with the def of LOGFONT
|
||||
|
||||
#define SYSTM_LOGFONT {16,7,0,0,700,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,VARIABLE_PITCH | FF_DONTCARE,"System"}
|
||||
#define HELVE_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,VARIABLE_PITCH | FF_DONTCARE, "MS Sans Serif"}
|
||||
#define COURI_LOGFONT {12,9,0,0,400,0,0,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_STROKE_PRECIS,PROOF_QUALITY,FIXED_PITCH | FF_DONTCARE, "Courier"}
|
||||
|
||||
DEVINFO devinfoVGA =
|
||||
{
|
||||
(GCAPS_OPAQUERECT | GCAPS_HORIZSTRIKE | GCAPS_ALTERNATEFILL | GCAPS_MONO_DITHER | GCAPS_COLOR_DITHER |
|
||||
GCAPS_WINDINGFILL | GCAPS_DITHERONREALIZE
|
||||
), // Graphics capabilities
|
||||
|
||||
SYSTM_LOGFONT, // Default font description
|
||||
HELVE_LOGFONT, // ANSI variable font description
|
||||
COURI_LOGFONT, // ANSI fixed font description
|
||||
0, // Count of device fonts
|
||||
BMF_4BPP, // preferred DIB format
|
||||
8, // Width of color dither
|
||||
8, // Height of color dither
|
||||
0 // Default palette to use for this device
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
//
|
||||
// PDEV
|
||||
// DESCRIPTION
|
||||
// This structure will contain all state information
|
||||
// required to maintain the video device
|
||||
// ACCESS
|
||||
// Allocated from non-paged pool by the GDI
|
||||
|
||||
typedef struct _PDEV
|
||||
{
|
||||
HANDLE KMDriver;
|
||||
HDEV GDIDevHandle;
|
||||
} PDEV, *PPDEV;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.1 2000/03/10 12:45:44 jfilby Exp $
|
||||
# $Id: makefile,v 1.2 2000/03/17 21:02:57 jfilby Exp $
|
||||
#
|
||||
# Makefile for ReactOS vgaddi.dll
|
||||
#
|
||||
|
@ -19,10 +19,10 @@ endif
|
|||
all: $(DLLTARGET)
|
||||
|
||||
MAIN_OBJECTS = main/enable.o
|
||||
|
||||
OTHER_OBJECTS = objects/screen.o
|
||||
RESOURCE_OBJECTS = $(TARGET).coff
|
||||
|
||||
OBJECTS = $(MAIN_OBJECTS) $(RESOURCE_OBJECTS)
|
||||
OBJECTS = $(MAIN_OBJECTS) $(OTHER_OBJECTS) $(RESOURCE_OBJECTS)
|
||||
|
||||
$(TARGET).a: $(OBJECTS)
|
||||
$(AR) csr $(TARGET).a $(OBJECTS)
|
||||
|
|
167
reactos/drivers/dd/vga/display/objects/screen.c
Normal file
167
reactos/drivers/dd/vga/display/objects/screen.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
#include "..\vgaddi.h"
|
||||
|
||||
static WORD PaletteBuffer[] = {
|
||||
16, 0, // 16 entries, start with 0
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
};
|
||||
|
||||
static BYTE ColorBuffer[] = {
|
||||
16, // 16 entries
|
||||
0, 0,
|
||||
0, // start with 0
|
||||
0x00, 0x00, 0x00, 0x00, // black
|
||||
0x2A, 0x00, 0x15, 0x00, // red
|
||||
0x00, 0x2A, 0x15, 0x00, // green
|
||||
0x2A, 0x2A, 0x15, 0x00, // brown
|
||||
0x00, 0x00, 0x2A, 0x00, // blue
|
||||
0x2A, 0x15, 0x2A, 0x00, // magenta
|
||||
0x15, 0x2A, 0x2A, 0x00, // cyan
|
||||
0x21, 0x22, 0x23, 0x00, // dark gray
|
||||
0x30, 0x31, 0x32, 0x00, // light gray
|
||||
0x3F, 0x00, 0x00, 0x00, // bright red
|
||||
0x00, 0x3F, 0x00, 0x00, // bright green
|
||||
0x3F, 0x3F, 0x00, 0x00, // bright yellow
|
||||
0x00, 0x00, 0x3F, 0x00, // bright blue
|
||||
0x3F, 0x00, 0x3F, 0x00, // bright magenta
|
||||
0x00, 0x3F, 0x3F, 0x00, // bright cyan
|
||||
0x3F, 0x3F, 0x3F, 0x00 // bright white
|
||||
};
|
||||
|
||||
DWORD getAvailableModes(HANDLE Driver,
|
||||
PVIDEO_MODE_INFORMATION *modeInformation,
|
||||
DWORD *ModeSize)
|
||||
{
|
||||
ULONG Temp;
|
||||
VIDEO_NUM_MODES modes;
|
||||
PVIDEO_MODE_INFORMATION VideoTemp;
|
||||
|
||||
// get number of modes supported
|
||||
if (EngDeviceIoControl(Driver,
|
||||
IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,
|
||||
NULL,
|
||||
0,
|
||||
&modes,
|
||||
sizeof(VIDEO_NUM_MODES),
|
||||
&Temp))
|
||||
{
|
||||
// get modes failed
|
||||
return(0);
|
||||
}
|
||||
|
||||
*ModeSize = modes.ModeInformationLength;
|
||||
|
||||
// allocate buffer for the mini-port to write the modes in
|
||||
*modeInformation = (PVIDEO_MODE_INFORMATION)
|
||||
EngAllocMem(0, modes.NumModes *
|
||||
modes.ModeInformationLength, ALLOC_TAG);
|
||||
|
||||
if (*modeInformation == (PVIDEO_MODE_INFORMATION) NULL)
|
||||
{
|
||||
// couldn't allocate buffer
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ask the mini-port to fill in the available modes.
|
||||
if (EngDeviceIoControl(Driver,
|
||||
IOCTL_VIDEO_QUERY_AVAIL_MODES,
|
||||
NULL,
|
||||
0,
|
||||
*modeInformation,
|
||||
modes.NumModes * modes.ModeInformationLength,
|
||||
&Temp))
|
||||
{
|
||||
// failed to query modes
|
||||
EngFreeMem(*modeInformation);
|
||||
*modeInformation = (PVIDEO_MODE_INFORMATION) NULL;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
// Which modes supported by miniport driver are also suppoted by us, the
|
||||
// display driver
|
||||
|
||||
Temp = modes.NumModes;
|
||||
VideoTemp = *modeInformation;
|
||||
|
||||
// Reject mode if it's not 4 planes or not graphic or not 1 bits per pel
|
||||
while (Temp--)
|
||||
{
|
||||
if ((VideoTemp->NumberOfPlanes != 4 ) ||
|
||||
!(VideoTemp->AttributeFlags & VIDEO_MODE_GRAPHICS) ||
|
||||
(VideoTemp->BitsPerPlane != 1) ||
|
||||
BROKEN_RASTERS(VideoTemp->ScreenStride,
|
||||
VideoTemp->VisScreenHeight))
|
||||
|
||||
{
|
||||
VideoTemp->Length = 0;
|
||||
}
|
||||
|
||||
VideoTemp = (PVIDEO_MODE_INFORMATION)
|
||||
(((PUCHAR)VideoTemp) + modes.ModeInformationLength);
|
||||
}
|
||||
|
||||
return modes.NumModes;
|
||||
}
|
||||
|
||||
BOOL InitVGA(PPDEV ppdev, BOOL bFirst)
|
||||
{
|
||||
UINT ReturnedDataLength;
|
||||
VIDEO_MEMORY VideoMemory;
|
||||
VIDEO_MEMORY_INFORMATION VideoMemoryInfo;
|
||||
|
||||
ppdev->ModeNum = 12;
|
||||
|
||||
// Set the mode that was requested
|
||||
if (EngDeviceIoControl(ppdev->KMDriver,
|
||||
IOCTL_VIDEO_SET_CURRENT_MODE,
|
||||
&ppdev->ModeNum,
|
||||
sizeof(VIDEO_MODE),
|
||||
NULL,
|
||||
0,
|
||||
&ReturnedDataLength)) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// set up internal palette
|
||||
if (EngDeviceIoControl(ppdev->KMDriver,
|
||||
IOCTL_VIDEO_SET_PALETTE_REGISTERS,
|
||||
(PVOID) PaletteBuffer,
|
||||
sizeof (PaletteBuffer),
|
||||
NULL,
|
||||
0,
|
||||
&ReturnedDataLength)) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
// set up the DAC
|
||||
if (EngDeviceIoControl(ppdev->KMDriver,
|
||||
IOCTL_VIDEO_SET_COLOR_REGISTERS,
|
||||
(PVOID) ColorBuffer,
|
||||
sizeof (ColorBuffer),
|
||||
NULL,
|
||||
0,
|
||||
&ReturnedDataLength)) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (bFirst) {
|
||||
|
||||
// map video memory into virtual memory
|
||||
VideoMemory.RequestedVirtualAddress = NULL;
|
||||
|
||||
if (EngDeviceIoControl(ppdev->KMDriver,
|
||||
IOCTL_VIDEO_MAP_VIDEO_MEMORY,
|
||||
(PVOID) &VideoMemory,
|
||||
sizeof (VIDEO_MEMORY),
|
||||
(PVOID) &VideoMemoryInfo,
|
||||
sizeof (VideoMemoryInfo),
|
||||
&ReturnedDataLength)) {
|
||||
// Failed to map to virtual memory
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
ppdev->fbScreen = VideoMemoryInfo.FrameBufferBase;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -1 +1,208 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <ddk/winddi.h>
|
||||
#include <ddk/ntddvid.h>
|
||||
|
||||
HANDLE GdiHeap;
|
||||
|
||||
#define DS_SOLIDBRUSH 0x00000001
|
||||
#define DS_GREYBRUSH 0x00000002
|
||||
#define DS_BRUSH 0x00000004
|
||||
#define DS_DIB 0x00000008
|
||||
|
||||
#define POW2(stride) (!((stride) & ((stride)-1))) // TRUE if stride is power of 2
|
||||
#define BROKEN_RASTERS(stride,cy) ((!(POW2(stride))) && ((stride*cy) > 0x10000))
|
||||
|
||||
#define DM_SPECVERSION 1 // FIXME: What is this really?
|
||||
#define ENUM_RECT_LIMIT 50
|
||||
|
||||
typedef struct _RECT_ENUM
|
||||
{
|
||||
ULONG c;
|
||||
RECTL arcl[ENUM_RECT_LIMIT];
|
||||
} RECT_ENUM;
|
||||
|
||||
// Cursor coordinates
|
||||
typedef struct _XYPAIR
|
||||
{
|
||||
USHORT x;
|
||||
USHORT y;
|
||||
} XYPAIR;
|
||||
|
||||
// Cursor states
|
||||
#define CURSOR_DOWN 0x00000001
|
||||
#define CURSOR_COLOR 0x00000004
|
||||
#define CURSOR_HW 0x00000010
|
||||
#define CURSOR_HW_ACTIVE 0x00000020
|
||||
#define CURSOR_ANIMATE 0x00000040
|
||||
|
||||
typedef struct _PDEV
|
||||
{
|
||||
ULONG fl; // driver flags
|
||||
|
||||
// Handles
|
||||
HANDLE KMDriver;
|
||||
HDEV GDIDevHandle; // engine's handle to PDEV
|
||||
HSURF SurfHandle; // engine's handle to surface
|
||||
PVOID AssociatedSurf; // associated surface
|
||||
|
||||
// Cursor
|
||||
XYPAIR xyCursor; // cursor position
|
||||
POINTL ptlExtent; // cursor extent
|
||||
ULONG cExtent; // effective cursor extent
|
||||
ULONG flCursor; // cursor status
|
||||
|
||||
// Pointer
|
||||
PVIDEO_POINTER_ATTRIBUTES pPointerAttributes; // HW Pointer Attributes
|
||||
ULONG XorMaskStartOffset; // Start offset of hardware pointer
|
||||
// XOR mask relative to AND mask for
|
||||
// passing to HW pointer
|
||||
DWORD PointerAttributes; // Size of buffer allocated
|
||||
DWORD flPreallocSSBBufferInUse; // True if preallocated saved screen
|
||||
// bits buffer is in use
|
||||
PUCHAR pjPreallocSSBBuffer; // Pointer to preallocated saved screen
|
||||
// bits buffer, if there is one
|
||||
ULONG ulPreallocSSBSize; // Size of preallocated saved screen
|
||||
// bits buffer
|
||||
VIDEO_POINTER_CAPABILITIES PointerCapabilities; // HW pointer abilities
|
||||
PUCHAR pucDIB4ToVGAConvBuffer; // DIB4->VGA conversion table buffer
|
||||
PUCHAR pucDIB4ToVGAConvTables; // Pointer to DIB4->VGA conversion
|
||||
|
||||
// Misc
|
||||
|
||||
ULONG ModeNum; // mode index for current VGA mode
|
||||
|
||||
SIZEL sizeSurf; // displayed size of the surface
|
||||
|
||||
PBYTE fbScreen; // pointer to the frame buffer
|
||||
|
||||
RECTL SavedBitsRight; // invisible part right of screen
|
||||
RECTL SavedBitsBottom; // invisible part at the bottom of the screen
|
||||
BOOL BitsSaved; // TRUE if bits are currently saved
|
||||
SIZEL sizeMem; // actual size (in pixels) of video memory
|
||||
LONG NumScansUsedByPointer; // # scans of offscreen memory used by
|
||||
|
||||
} PDEV, *PPDEV;
|
||||
|
||||
typedef struct {
|
||||
RECTL BankBounds; // Pixels addressable in this bank
|
||||
ULONG BankOffset; // Offset of bank start from bitmap start if linearly addressable
|
||||
} BANK_INFO, *PBANK_INFO;
|
||||
|
||||
typedef enum {
|
||||
JustifyTop = 0,
|
||||
JustifyBottom,
|
||||
} BANK_JUST;
|
||||
|
||||
// bank control function vector
|
||||
//typedef VOID (*PFN_BankControl)(PDEVSURF, ULONG, BANK_JUST);
|
||||
typedef VOID (*PFN_BankControl)(PVOID, ULONG, BANK_JUST);
|
||||
|
||||
// descriptor for a saved screen bits block
|
||||
|
||||
typedef struct _SAVED_SCREEN_BITS
|
||||
{
|
||||
BOOL bFlags;
|
||||
PBYTE pjBuffer; // pointer to save buffer start
|
||||
ULONG ulSize; // size of save buffer (per plane; display memory only)
|
||||
ULONG ulSaveWidthInBytes; // # of bytes across save area (including
|
||||
// partial edge bytes, if any)
|
||||
ULONG ulDelta; // # of bytes from end of one saved scan's saved bits to
|
||||
// start of next (system memory only)
|
||||
PVOID pvNextSSB; // pointer to next saved screen bits block
|
||||
// for system memory blocks, saved bits start immediately
|
||||
// after this structure
|
||||
} SAVED_SCREEN_BITS, *PSAVED_SCREEN_BITS;
|
||||
|
||||
// DEVSURF -- definition of a surface as seen and used by the various VGA
|
||||
// drivers
|
||||
|
||||
typedef struct _DEVSURF
|
||||
{
|
||||
IDENT ident; // Identifier for debugging ease
|
||||
ULONG flSurf; // DS_ flags as defined below
|
||||
BYTE Color; // Solid color surface if DS_SOLIDBRUSH
|
||||
|
||||
// If DS_SOLIDBRUSH, the following fields are undefined and not guaranteed to
|
||||
// have been allocated!
|
||||
|
||||
BYTE Format; // BMF_*, BMF_PHYSDEVICE
|
||||
BYTE jReserved1; // Reserved
|
||||
BYTE jReserved2; // Reserved
|
||||
PPDEV ppdev; // Pointer to associated PDEV
|
||||
SIZEL sizeSurf; // Size of the surface
|
||||
ULONG NextScan; // Offset from scan "n" to "n+1"
|
||||
ULONG NextPlane; // Offset from plane "n" to "n+1"
|
||||
PVOID Scan0; // Pointer to scan 0 of bitmap
|
||||
// (actual address of start of bank, for banked VGA surface)
|
||||
PVOID StartBmp; // Pointer to start of bitmap
|
||||
PVOID Conv; // Pointer to DIB/Planer conversion buffer
|
||||
|
||||
// Banking variables; used only for banked VGA surfaces
|
||||
|
||||
PVIDEO_BANK_SELECT BankSelectInfo;
|
||||
ULONG Bank2RWSkip; // Offset from one bank index to next to make two 32K banks appear to be
|
||||
// one seamless 64K bank
|
||||
PFN pfnBankSwitchCode;
|
||||
VIDEO_BANK_TYPE BankingType;
|
||||
ULONG BitmapSize; // Length of bitmap if there were no banking, in CPU addressable bytes
|
||||
ULONG PtrBankScan; // Last scan line in pointer work bank
|
||||
RECTL WindowClip1; // Single-window banking clip rect
|
||||
RECTL WindowClip2[2]; // Double-window banking clip rects for
|
||||
// windows 0 & 1
|
||||
ULONG WindowBank[2]; // Current banks mapped into windows
|
||||
// 0 & 1 (used in 2 window mode only)
|
||||
PBANK_INFO BankInfo; // Pointer to array of bank clip info
|
||||
ULONG BankInfoLength; // Length of pbiBankInfo, in entries
|
||||
PBANK_INFO BankInfo2RW; // Same as above, but for 2RW window
|
||||
ULONG BankInfo2RWLength; // case
|
||||
PFN_BankControl pfnBankControl; // Pointer to bank control function
|
||||
PFN_BankControl pfnBankControl2Window; // Pointer to double-window bank
|
||||
// control function
|
||||
PVOID BitmapStart; // Single-window bitmap start pointer (adjusted as
|
||||
// necessary to make window map in at proper offset)
|
||||
PVOID BitmapStart2Window[2]; // Double-window window 0 and 1 bitmap start
|
||||
PVOID BankBufferPlane0; // Pointer to temp buffer capable of
|
||||
// storing one full bank for plane 0 for 1
|
||||
// R/W case; capable of storing one full
|
||||
// bank height of edge bytes for all four
|
||||
// planes for the 1R/1W case. Also used to
|
||||
// point to text building buffer in all
|
||||
// cases. This is the pointer used to
|
||||
// dealloc bank working storage for all
|
||||
// four planes
|
||||
|
||||
// The following 3 pointers used by 1 R/W banked devices
|
||||
|
||||
PVOID BankBufferPlane1; // Like above, but for plane 1
|
||||
PVOID BankBufferPlane2; // Like above, but for plane 2
|
||||
PVOID BankBufferPlane3; // Like above, but for plane 3
|
||||
ULONG TempBufferSize; // Full size of temp buffer pointed to
|
||||
// by pvBankBufferPlane0
|
||||
|
||||
ULONG ajBits[1]; // Bits will start here for device bitmaps
|
||||
PSAVED_SCREEN_BITS ssbList; // Pointer to start of linked list of
|
||||
// saved screen bit blocks
|
||||
} DEVSURF, *PDEVSURF;
|
||||
|
||||
typedef VOID (*PFN_ScreenToScreenBlt)(PDEVSURF, PRECTL, PPOINTL, INT);
|
||||
|
||||
// BMF_PHYSDEVICE format type
|
||||
|
||||
#define BMF_PHYSDEVICE 0xFF
|
||||
#define BMF_DFB 0xFE
|
||||
|
||||
// Identifiers used in debugging (DEVSURF.ident)
|
||||
|
||||
#define PDEV_IDENT ('V' + ('P' << 8) + ('D' << 16) + ('V' << 24))
|
||||
#define DEVSURF_IDENT ('V' + ('S' << 8) + ('R' << 16) + ('F' << 24))
|
||||
|
||||
BOOL InitVGA(PPDEV ppdev, BOOL bFirst); // screen.c: initialize VGA mode
|
||||
|
||||
#define DRIVER_EXTRA_SIZE 0
|
||||
#define ALLOC_TAG 'agvD' // Dvga reversed
|
||||
#define DLL_NAME L"vga" // DLL name in Unicode
|
||||
|
||||
#define MAX_SCAN_WIDTH 2048 // pixels
|
||||
#define DRIVER_OFFSCREEN_REFRESHED 0x04L // if not set, don't use offscreen memory
|
||||
#define PLANAR_PELS_PER_CPU_ADDRESS 8
|
||||
#define PACKED_PELS_PER_CPU_ADDRESS 2
|
||||
|
|
102
reactos/drivers/dd/vga/miniport/initvga.c
Normal file
102
reactos/drivers/dd/vga/miniport/initvga.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
#include <internal/i386/io.h>
|
||||
|
||||
#include "vgaVideo.h"
|
||||
|
||||
void outxay(unsigned short ad, unsigned char x, unsigned char y)
|
||||
{
|
||||
unsigned short xy = (x << 8) + y;
|
||||
VideoPortWritePortUshort(ad, xy);
|
||||
}
|
||||
|
||||
void setMode(VideoMode mode)
|
||||
{
|
||||
unsigned char x;
|
||||
|
||||
VideoPortWritePortUchar((PUCHAR)MISC, mode.Misc);
|
||||
VideoPortWritePortUchar((PUCHAR)STATUS, 0);
|
||||
VideoPortWritePortUchar((PUCHAR)FEATURE, mode.Feature);
|
||||
|
||||
for(x=0; x<5; x++)
|
||||
{
|
||||
outxay(SEQ, mode.Seq[x], x);
|
||||
}
|
||||
|
||||
VideoPortWritePortUshort((USHORT)CRTC, 0x11);
|
||||
VideoPortWritePortUshort((USHORT)CRTC, (mode.Crtc[0x11] & 0x7f));
|
||||
|
||||
for(x=0; x<25; x++)
|
||||
{
|
||||
outxay(CRTC, mode.Crtc[x], x);
|
||||
}
|
||||
|
||||
for(x=0; x<9; x++)
|
||||
{
|
||||
outxay(GRAPHICS, mode.Gfx[x], x);
|
||||
}
|
||||
|
||||
x=VideoPortReadPortUchar(FEATURE);
|
||||
|
||||
for(x=0; x<21; x++)
|
||||
{
|
||||
VideoPortWritePortUchar((PUCHAR)ATTRIB, x);
|
||||
VideoPortWritePortUchar((PUCHAR)ATTRIB, mode.Attrib[x]);
|
||||
}
|
||||
|
||||
x=VideoPortReadPortUchar(STATUS);
|
||||
|
||||
VideoPortWritePortUchar(ATTRIB, 0x20);
|
||||
}
|
||||
|
||||
VideoMode Mode12 = {
|
||||
0xa000, 0xe3, 0x00,
|
||||
|
||||
{0x02, 0x01, 0x0f, 0x00, 0x06},
|
||||
|
||||
{0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x59, 0xea, 0x8c, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
|
||||
0xff},
|
||||
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x0f, 0xff},
|
||||
|
||||
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f, 0x81, 0x00, 0x0f, 0x00, 0x00}
|
||||
};
|
||||
|
||||
VideoMode Mode13 = {
|
||||
0xa000, 0x63, 0x00,
|
||||
|
||||
{0x03, 0x01, 0x0f, 0x00, 0x0e},
|
||||
|
||||
{0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0xbf, 0x1f, 0x00, 0x41, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x9c, 0x0e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
|
||||
0xff},
|
||||
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x07, 0x0f, 0xff},
|
||||
|
||||
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||
0x0c, 0x0d, 0x0e, 0x0f, 0x41, 0x00, 0x0f, 0x00, 0x00}
|
||||
};
|
||||
|
||||
void myvgaPutPixel(int x, int y, unsigned char c)
|
||||
{
|
||||
unsigned offset;
|
||||
unsigned char a;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
|
||||
VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
|
||||
VideoPortWritePortUchar((PUCHAR)0x3cf,maskbit[x]); // the MASK
|
||||
VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
|
||||
// read mode = 0 (bit 3
|
||||
a = vidmem[offset]; // Update bit buffer
|
||||
vidmem[offset] = c; // Write the pixel
|
||||
}
|
||||
|
||||
void InitVGAMode()
|
||||
{
|
||||
// vidmem += __djgpp_conventional_base;
|
||||
|
||||
setMode(Mode12);
|
||||
RtlZeroMemory(vidmem, 38400);
|
||||
vgaPreCalc();
|
||||
}
|
69
reactos/drivers/dd/vga/miniport/makefile
Normal file
69
reactos/drivers/dd/vga/miniport/makefile
Normal file
|
@ -0,0 +1,69 @@
|
|||
# $Id: makefile,v 1.1 2000/03/17 21:02:57 jfilby Exp $
|
||||
#
|
||||
#
|
||||
BASE_CFLAGS = -I../../../../include
|
||||
|
||||
MP_OBJECTS = vgamp.o initvga.o vgavideo.o vgamp.coff ../../../../ntoskrnl/ntoskrnl.a ../../vidport/vidport.a
|
||||
|
||||
all: vgamp.sys
|
||||
|
||||
.phony: all
|
||||
|
||||
clean:
|
||||
- $(RM) *.o
|
||||
- $(RM) junk.tmp
|
||||
- $(RM) base.tmp
|
||||
- $(RM) temp.exp
|
||||
- $(RM) *.sys
|
||||
- $(RM) *.coff
|
||||
|
||||
.phony: clean
|
||||
|
||||
vgamp.sys: $(MP_OBJECTS)
|
||||
$(CC) \
|
||||
-specs=../../../svc_specs \
|
||||
-mdll \
|
||||
-o junk.tmp \
|
||||
-Wl,--defsym,_end=end \
|
||||
-Wl,--defsym,_edata=__data_end__ \
|
||||
-Wl,--defsym,_etext=etext \
|
||||
-Wl,--base-file,base.tmp \
|
||||
$(MP_OBJECTS)
|
||||
- $(RM) junk.tmp
|
||||
$(DLLTOOL) \
|
||||
--dllname vgamp.sys \
|
||||
--base-file base.tmp \
|
||||
--output-exp temp.exp \
|
||||
--kill-at
|
||||
- $(RM) base.tmp
|
||||
$(CC) \
|
||||
--verbose \
|
||||
-Wl,--image-base,0x10000 \
|
||||
-Wl,-e,_DriverEntry@8 \
|
||||
-Wl,temp.exp \
|
||||
-specs=../../../svc_specs \
|
||||
-mdll \
|
||||
-o vgamp.sys \
|
||||
$(MP_OBJECTS)
|
||||
- $(RM) temp.exp
|
||||
|
||||
floppy: $(FLOPPY_DIR)/drivers/vgamp.sys
|
||||
|
||||
$(FLOPPY_DIR)/drivers/vgamp.sys: vgamp.sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) vgamp.sys $(FLOPPY_DIR)\drivers\vgamp.sys
|
||||
else
|
||||
$(CP) vgamp.sys $(FLOPPY_DIR)/drivers/vgamp.sys
|
||||
endif
|
||||
|
||||
dist: ../../../../$(DIST_DIR)/drivers/vgamp.sys
|
||||
|
||||
../../../../$(DIST_DIR)/drivers/vgamp.sys: vgamp.sys
|
||||
ifeq ($(DOSCLI),yes)
|
||||
$(CP) vgamp.sys ..\..\..\..\$(DIST_DIR)\drivers\vgamp.sys
|
||||
else
|
||||
$(CP) vgamp.sys ../../../../$(DIST_DIR)/drivers/vgamp.sys
|
||||
endif
|
||||
|
||||
include ../../../../rules.mak
|
||||
|
|
@ -397,13 +397,27 @@ VOID VGAResetDevice(OUT PSTATUS_BLOCK StatusBlock)
|
|||
VOID VGASetColorRegisters(IN PVIDEO_CLUT ColorLookUpTable,
|
||||
OUT PSTATUS_BLOCK StatusBlock)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
int i;
|
||||
|
||||
VideoPortWritePortUchar(0x03c8, ColorLookUpTable->FirstEntry);
|
||||
|
||||
for (i=0; i<ColorLookUpTable->NumEntries; i++)
|
||||
{
|
||||
VideoPortWritePortUchar(0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Red);
|
||||
VideoPortWritePortUchar(0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Green);
|
||||
VideoPortWritePortUchar(0x03c9, ColorLookUpTable->LookupTable[i].RgbArray.Blue);
|
||||
}
|
||||
}
|
||||
|
||||
VOID VGASetCurrentMode(IN PVIDEO_MODE RequestedMode,
|
||||
OUT PSTATUS_BLOCK StatusBlock)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
if(RequestedMode->RequestedMode == 12)
|
||||
{
|
||||
InitVGAMode();
|
||||
} else {
|
||||
DbgPrint("Unrecognised mode for VGASetCurrentMode\n");
|
||||
}
|
||||
}
|
||||
|
||||
VOID VGAShareVideoMemory(IN PVIDEO_SHARE_MEMORY RequestedMemory,
|
||||
|
@ -424,6 +438,3 @@ VOID VGAUnshareVideoMemory(IN PVIDEO_MEMORY MemoryToUnshare,
|
|||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
278
reactos/drivers/dd/vga/miniport/vgavideo.c
Normal file
278
reactos/drivers/dd/vga/miniport/vgavideo.c
Normal file
|
@ -0,0 +1,278 @@
|
|||
#include "vgavideo.h"
|
||||
|
||||
#define VIDMEM_BASE 0xa0000
|
||||
char* vidmem = (char *)(VIDMEM_BASE);
|
||||
|
||||
div_t div(int num, int denom)
|
||||
{
|
||||
div_t r;
|
||||
if (num > 0 && denom < 0) {
|
||||
num = -num;
|
||||
denom = -denom;
|
||||
}
|
||||
r.quot = num / denom;
|
||||
r.rem = num % denom;
|
||||
if (num < 0 && denom > 0)
|
||||
{
|
||||
if (r.rem > 0)
|
||||
{
|
||||
r.quot++;
|
||||
r.rem -= denom;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int mod(int num, int denom)
|
||||
{
|
||||
div_t dvt = div(num, denom);
|
||||
return dvt.rem;
|
||||
}
|
||||
|
||||
VOID vgaPreCalc()
|
||||
{
|
||||
ULONG j;
|
||||
|
||||
startmasks[1] = 127;
|
||||
startmasks[2] = 63;
|
||||
startmasks[3] = 31;
|
||||
startmasks[4] = 15;
|
||||
startmasks[5] = 7;
|
||||
startmasks[6] = 3;
|
||||
startmasks[7] = 1;
|
||||
startmasks[8] = 255;
|
||||
|
||||
endmasks[0] = 128;
|
||||
endmasks[1] = 192;
|
||||
endmasks[2] = 224;
|
||||
endmasks[3] = 240;
|
||||
endmasks[4] = 248;
|
||||
endmasks[5] = 252;
|
||||
endmasks[6] = 254;
|
||||
endmasks[7] = 255;
|
||||
endmasks[8] = 255;
|
||||
|
||||
for(j=0; j<80; j++)
|
||||
{
|
||||
maskbit[j*8] = 128;
|
||||
maskbit[j*8+1] = 64;
|
||||
maskbit[j*8+2] = 32;
|
||||
maskbit[j*8+3] = 16;
|
||||
maskbit[j*8+4] = 8;
|
||||
maskbit[j*8+5] = 4;
|
||||
maskbit[j*8+6] = 2;
|
||||
maskbit[j*8+7] = 1;
|
||||
|
||||
bit8[j*8] = 7;
|
||||
bit8[j*8+1] = 6;
|
||||
bit8[j*8+2] = 5;
|
||||
bit8[j*8+3] = 4;
|
||||
bit8[j*8+4] = 3;
|
||||
bit8[j*8+5] = 2;
|
||||
bit8[j*8+6] = 1;
|
||||
bit8[j*8+7] = 0;
|
||||
}
|
||||
for(j=0; j<480; j++)
|
||||
{
|
||||
y80[j] = j*80;
|
||||
}
|
||||
for(j=0; j<640; j++)
|
||||
{
|
||||
xconv[j] = j >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
void vgaSetWriteMode(char mode)
|
||||
{
|
||||
VideoPortWritePortUchar((PUCHAR)0x03ce, 0x03);
|
||||
VideoPortWritePortUchar((PUCHAR)0x03cf, mode);
|
||||
}
|
||||
|
||||
void vgaSetColor(int cindex, int red, int green, int blue)
|
||||
{
|
||||
VideoPortWritePortUchar((PUCHAR)0x03c8, cindex);
|
||||
VideoPortWritePortUchar((PUCHAR)0x03c9, red);
|
||||
VideoPortWritePortUchar((PUCHAR)0x03c9, green);
|
||||
VideoPortWritePortUchar((PUCHAR)0x03c9, blue);
|
||||
}
|
||||
|
||||
void vgaPutPixel(int x, int y, unsigned char c)
|
||||
{
|
||||
unsigned offset;
|
||||
unsigned char a;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
|
||||
VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
|
||||
VideoPortWritePortUchar((PUCHAR)0x3cf,maskbit[x]); // the MASK
|
||||
VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
|
||||
// read mode = 0 (bit 3
|
||||
a = vidmem[offset]; // Update bit buffer
|
||||
vidmem[offset] = c; // Write the pixel
|
||||
}
|
||||
|
||||
void vgaPutByte(int x, int y, unsigned char c)
|
||||
{
|
||||
unsigned offset;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
|
||||
// Set mask to all pixels in byte
|
||||
VideoPortWritePortUchar((PUCHAR)0x3ce,0x08);
|
||||
VideoPortWritePortUchar((PUCHAR)0x3cf,0xff);
|
||||
|
||||
vidmem[offset]=c;
|
||||
}
|
||||
|
||||
void vgaGetByte(unsigned offset,
|
||||
unsigned char *b, unsigned char *g,
|
||||
unsigned char *r, unsigned char *i)
|
||||
{
|
||||
VideoPortWritePortUshort((PUSHORT)0x03ce, 0x0304);
|
||||
*i = vidmem[offset];
|
||||
VideoPortWritePortUshort((PUSHORT)0x03ce, 0x0204);
|
||||
*r = vidmem[offset];
|
||||
VideoPortWritePortUshort((PUSHORT)0x03ce, 0x0104);
|
||||
*g = vidmem[offset];
|
||||
VideoPortWritePortUshort((PUSHORT)0x03ce, 0x0004);
|
||||
*b = vidmem[offset];
|
||||
}
|
||||
|
||||
int vgaGetPixel(int x, int y)
|
||||
{
|
||||
unsigned char mask, b, g, r, i;
|
||||
unsigned offset;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
mask=maskbit[x];
|
||||
vgaGetByte(offset, &b, &g, &r, &i);
|
||||
b=b&mask;
|
||||
g=g&mask;
|
||||
r=r&mask;
|
||||
i=i&mask;
|
||||
|
||||
mask=bit8[x];
|
||||
g=g>>mask;
|
||||
b=b>>mask;
|
||||
r=r>>mask;
|
||||
i=i>>mask;
|
||||
|
||||
return(b+2*g+4*r+8*i);
|
||||
}
|
||||
|
||||
BOOL vgaHLine(int x, int y, int len, unsigned char c)
|
||||
{
|
||||
unsigned char a;
|
||||
unsigned int pre1, i;
|
||||
unsigned int orgpre1, orgx, midpre1;
|
||||
unsigned long leftpixs, midpixs, rightpixs, temp;
|
||||
|
||||
orgx=x;
|
||||
|
||||
if(len<8)
|
||||
{
|
||||
for (i=x; i<x+len; i++)
|
||||
vgaPutPixel(i, y, c);
|
||||
} else {
|
||||
|
||||
leftpixs=x;
|
||||
while(leftpixs>8) leftpixs-=8;
|
||||
temp = len;
|
||||
midpixs = 0;
|
||||
|
||||
while(temp>7)
|
||||
{
|
||||
temp-=8;
|
||||
midpixs++;
|
||||
}
|
||||
if((temp>=0) && (midpixs>0)) midpixs--;
|
||||
|
||||
pre1=xconv[x]+y80[y];
|
||||
orgpre1=pre1;
|
||||
|
||||
// Left
|
||||
if(leftpixs==8) {
|
||||
// Left edge should be an entire middle bar
|
||||
x=orgx;
|
||||
leftpixs=0;
|
||||
}
|
||||
else if(leftpixs>0)
|
||||
{
|
||||
VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
|
||||
VideoPortWritePortUchar((PUCHAR)0x3cf,startmasks[leftpixs]); // the MASK
|
||||
VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
|
||||
// read mode = 0 (bit 3
|
||||
a = vidmem[pre1]; // Update bit buffer
|
||||
vidmem[pre1] = c; // Write the pixel
|
||||
|
||||
// Middle
|
||||
x=orgx+(8-leftpixs)+leftpixs;
|
||||
|
||||
} else {
|
||||
// leftpixs == 0
|
||||
midpixs+=1;
|
||||
}
|
||||
|
||||
if(midpixs>0)
|
||||
{
|
||||
midpre1=xconv[x]+y80[y];
|
||||
|
||||
// Set mask to all pixels in byte
|
||||
VideoPortWritePortUchar((PUCHAR)0x3ce, 0x08);
|
||||
VideoPortWritePortUchar((PUCHAR)0x3cf, 0xff);
|
||||
memset(vidmem+midpre1, c, midpixs);
|
||||
}
|
||||
|
||||
rightpixs = len - ((midpixs*8) + leftpixs);
|
||||
|
||||
if((rightpixs>0))
|
||||
{
|
||||
x=(orgx+len)-rightpixs;
|
||||
|
||||
// Go backwards till we reach the 8-byte boundary
|
||||
while(mod(x, 8)!=0) { x--; rightpixs++; }
|
||||
|
||||
while(rightpixs>7)
|
||||
{
|
||||
// This is a BAD case as this should have been a midpixs
|
||||
|
||||
vgaPutByte(x, y, c);
|
||||
rightpixs-=8;
|
||||
x+=8;
|
||||
}
|
||||
|
||||
pre1=xconv[x]+y80[y];
|
||||
VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
|
||||
VideoPortWritePortUchar((PUCHAR)0x3cf,endmasks[rightpixs]); // the MASK
|
||||
VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
|
||||
// read mode = 0 (bit 3
|
||||
a = vidmem[pre1]; // Update bit buffer
|
||||
vidmem[pre1] = c; // Write the pixel
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL vgaVLine(int x, int y, int len, unsigned char c)
|
||||
{
|
||||
unsigned offset, i;
|
||||
unsigned char a;
|
||||
|
||||
offset = xconv[x]+y80[y];
|
||||
|
||||
VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
|
||||
VideoPortWritePortUchar((PUCHAR)0x3cf,maskbit[x]); // the MASK
|
||||
VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
|
||||
// read mode = 0 (bit 3)
|
||||
len++;
|
||||
|
||||
for(i=y; i<y+len; i++)
|
||||
{
|
||||
a = vidmem[offset]; // Update bit buffer
|
||||
vidmem[offset] = c; // Write the pixel
|
||||
offset+=80;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
33
reactos/drivers/dd/vga/miniport/vgavideo.h
Normal file
33
reactos/drivers/dd/vga/miniport/vgavideo.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <ddk/ntddvid.h>
|
||||
|
||||
#define VGA_NORMAL 0
|
||||
#define VGA_AND 8
|
||||
#define VGA_OR 16
|
||||
#define VGA_XOR 24
|
||||
|
||||
typedef struct { int quot, rem; } div_t;
|
||||
|
||||
int maskbit[640], y80[480], xconv[640], bit8[640], startmasks[8], endmasks[8];
|
||||
|
||||
char* vidmem;
|
||||
|
||||
#define MISC 0x3c2
|
||||
#define SEQ 0x3c4
|
||||
#define CRTC 0x3d4
|
||||
#define GRAPHICS 0x3ce
|
||||
#define FEATURE 0x3da
|
||||
#define ATTRIB 0x3c0
|
||||
#define STATUS 0x3da
|
||||
|
||||
typedef struct _VideoMode {
|
||||
unsigned short VidSeg;
|
||||
unsigned char Misc;
|
||||
unsigned char Feature;
|
||||
unsigned char Seq[5];
|
||||
unsigned char Crtc[25];
|
||||
unsigned char Gfx[9];
|
||||
unsigned char Attrib[21];
|
||||
} VideoMode;
|
||||
|
||||
VOID vgaPreCalc();
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: vidport.c,v 1.11 2000/03/01 03:25:11 ekohl Exp $
|
||||
/* $Id: vidport.c,v 1.12 2000/03/17 21:02:58 jfilby Exp $
|
||||
*
|
||||
* VideoPort driver
|
||||
* Written by Rex Jolliff
|
||||
|
@ -204,6 +204,8 @@ VideoPortInitialize(IN PVOID Context1,
|
|||
return Status;
|
||||
}
|
||||
|
||||
MPDriverObject->DeviceObject = MPDeviceObject;
|
||||
|
||||
/* initialize the miniport drivers dispatch table */
|
||||
MPDriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatchOpenClose;
|
||||
MPDriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatchOpenClose;
|
||||
|
@ -221,6 +223,7 @@ VideoPortInitialize(IN PVOID Context1,
|
|||
ExtensionData->DeviceObject = MPDeviceObject;
|
||||
|
||||
/* Set the buffering strategy here... */
|
||||
/* If you change this, remember to change VidDispatchDeviceControl too */
|
||||
MPDeviceObject->Flags |= DO_BUFFERED_IO;
|
||||
|
||||
/* Call HwFindAdapter entry point */
|
||||
|
@ -754,7 +757,31 @@ static NTSTATUS
|
|||
VidDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PVIDEO_REQUEST_PACKET vrp;
|
||||
|
||||
DbgPrint("IO Control code: %u\n", Irp->Stack[0].Parameters.DeviceIoControl.IoControlCode);
|
||||
|
||||
// Translate the IRP to a VRP
|
||||
vrp = ExAllocatePool(PagedPool, sizeof(VIDEO_REQUEST_PACKET));
|
||||
vrp->StatusBlock = ExAllocatePool(PagedPool, sizeof(STATUS_BLOCK));
|
||||
vrp->IoControlCode = Irp->Stack[0].Parameters.DeviceIoControl.IoControlCode;
|
||||
|
||||
// We're assuming METHOD_BUFFERED
|
||||
vrp->InputBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||
vrp->InputBufferLength = Irp->Stack[0].Parameters.DeviceIoControl.InputBufferLength;
|
||||
vrp->OutputBuffer = Irp->UserBuffer;
|
||||
vrp->OutputBufferLength = Irp->Stack[0].Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
// Call the Miniport Driver with the VRP
|
||||
DeviceObject->DriverObject->DriverStartIo(DeviceObject->DeviceExtension, vrp);
|
||||
|
||||
// Translate the VRP back into the IRP for OutputBuffer
|
||||
Irp->UserBuffer = vrp->OutputBuffer;
|
||||
Irp->Stack[0].Parameters.DeviceIoControl.OutputBufferLength = vrp->OutputBufferLength;
|
||||
|
||||
// Free the VRP
|
||||
ExFreePool(vrp->StatusBlock);
|
||||
ExFreePool(vrp);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,12 +29,95 @@
|
|||
|
||||
typedef LONG VP_STATUS, *PVP_STATUS;
|
||||
|
||||
// Bit definitions for Attribute Flags
|
||||
#define VIDEO_MODE_COLOR 0x0001
|
||||
#define VIDEO_MODE_GRAPHICS 0x0002
|
||||
#define VIDEO_MODE_PALETTE_DRIVEN 0x0004
|
||||
|
||||
#define VIDEO_MEMORY_SPACE_MEMORY 0x00
|
||||
#define VIDEO_MEMORY_SPACE_IO 0x01
|
||||
#define VIDEO_MEMORY_SPACE_USER_MODE 0x02
|
||||
#define VIDEO_MEMORY_SPACE_DENSE 0x04
|
||||
#define VIDEO_MEMORY_SPACE_P6CACHE 0x08
|
||||
|
||||
typedef struct _VIDEO_POINTER_CAPABILITIES {
|
||||
ULONG Flags;
|
||||
ULONG MaxWidth;
|
||||
ULONG MaxHeight;
|
||||
ULONG HWPtrBitmapStart;
|
||||
ULONG HWPtrBitmapEnd;
|
||||
} VIDEO_POINTER_CAPABILITIES, *PVIDEO_POINTER_CAPABILITIES;
|
||||
|
||||
typedef struct _VIDEO_POINTER_ATTRIBUTES {
|
||||
ULONG Flags;
|
||||
ULONG Width;
|
||||
ULONG Height;
|
||||
ULONG WidthInBytes;
|
||||
ULONG Enable;
|
||||
SHORT Column;
|
||||
SHORT Row;
|
||||
UCHAR Pixels[1];
|
||||
} VIDEO_POINTER_ATTRIBUTES, *PVIDEO_POINTER_ATTRIBUTES;
|
||||
|
||||
typedef enum _VIDEO_BANK_TYPE {
|
||||
VideoNotBanked = 0,
|
||||
VideoBanked1RW,
|
||||
VideoBanked1R1W,
|
||||
VideoBanked2RW,
|
||||
NumVideoBankTypes
|
||||
} VIDEO_BANK_TYPE, *PVIDEO_BANK_TYPE;
|
||||
|
||||
typedef struct _VIDEO_BANK_SELECT {
|
||||
ULONG Length;
|
||||
ULONG Size;
|
||||
ULONG BankingFlags;
|
||||
ULONG BankingType;
|
||||
ULONG PlanarHCBankingType;
|
||||
ULONG BitmapWidthInBytes;
|
||||
ULONG BitmapSize;
|
||||
ULONG Granularity;
|
||||
ULONG PlanarHCGranularity;
|
||||
ULONG CodeOffset;
|
||||
ULONG PlanarHCBankCodeOffset;
|
||||
ULONG PlanarHCEnableCodeOffset;
|
||||
ULONG PlanarHCDisableCodeOffset;
|
||||
} VIDEO_BANK_SELECT, *PVIDEO_BANK_SELECT;
|
||||
|
||||
typedef struct _VIDEO_CLUTDATA {
|
||||
UCHAR Red;
|
||||
UCHAR Green;
|
||||
UCHAR Blue;
|
||||
UCHAR Unused;
|
||||
} VIDEO_CLUTDATA, *PVIDEO_CLUTDATA;
|
||||
|
||||
typedef struct _VIDEO_NUM_MODES {
|
||||
ULONG NumModes;
|
||||
ULONG ModeInformationLength;
|
||||
} VIDEO_NUM_MODES, *PVIDEO_NUM_MODES;
|
||||
|
||||
typedef struct _VIDEO_MODE_INFORMATION {
|
||||
ULONG Length;
|
||||
ULONG ModeIndex;
|
||||
ULONG VisScreenWidth;
|
||||
ULONG VisScreenHeight;
|
||||
ULONG ScreenStride;
|
||||
ULONG NumberOfPlanes;
|
||||
ULONG BitsPerPlane;
|
||||
ULONG Frequency;
|
||||
ULONG XMillimeter;
|
||||
ULONG YMillimeter;
|
||||
ULONG NumberRedBits;
|
||||
ULONG NumberGreenBits;
|
||||
ULONG NumberBlueBits;
|
||||
ULONG RedMask;
|
||||
ULONG GreenMask;
|
||||
ULONG BlueMask;
|
||||
ULONG AttributeFlags;
|
||||
ULONG VideoMemoryBitmapWidth;
|
||||
ULONG VideoMemoryBitmapHeight;
|
||||
ULONG DriverSpecificAttributeFlags;
|
||||
} VIDEO_MODE_INFORMATION, *PVIDEO_MODE_INFORMATION;
|
||||
|
||||
typedef enum _VIDEO_DEVICE_DATA_TYPE
|
||||
{
|
||||
VpMachineData,
|
||||
|
@ -187,8 +270,14 @@ typedef struct _VIDEO_X86_BIOS_ARGUMENTS
|
|||
|
||||
typedef VOID (*PBANKED_SECTION_ROUTINE)(IN ULONG ReadBank, IN ULONG WriteBank, IN PVOID Context);
|
||||
|
||||
/* FIXME: replace with proper typedefs */
|
||||
typedef PVOID PVIDEO_CLUT;
|
||||
typedef struct {
|
||||
USHORT NumEntries;
|
||||
USHORT FirstEntry;
|
||||
union {
|
||||
VIDEO_CLUTDATA RgbArray;
|
||||
ULONG RgbLong;
|
||||
} LookupTable[1];
|
||||
} VIDEO_CLUT, *PVIDEO_CLUT;
|
||||
|
||||
typedef struct _VIDEO_MEMORY
|
||||
{
|
||||
|
@ -208,10 +297,6 @@ typedef struct _VIDEO_MODE
|
|||
ULONG RequestedMode;
|
||||
} VIDEO_MODE, *PVIDEO_MODE;
|
||||
|
||||
/* FIXME: replace with proper typedefs */
|
||||
typedef PVOID PVIDEO_MODE_INFORMATION;
|
||||
typedef PVOID PVIDEO_NUM_MODES;
|
||||
|
||||
typedef struct _VIDEO_SHARE_MEMORY
|
||||
{
|
||||
HANDLE ProcessHandle;
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
typedef DWORD PTRDIFF;
|
||||
#endif
|
||||
|
||||
#define GDI_DRIVER_VERSION 0x4000 // NT 4 compatibility
|
||||
|
||||
/* FIXME: find definitions for these structs */
|
||||
typedef PVOID PCOLORADJUSTMENT;
|
||||
typedef PVOID PDD_CALLBACKS;
|
||||
|
@ -48,6 +50,15 @@ typedef PVOID PVIDEOMEMORY;
|
|||
/* FIXME: how big should this constant be? */
|
||||
#define HS_DDI_MAX 6
|
||||
|
||||
/* XLate types */
|
||||
#define XO_TRIVIAL 0x00000001
|
||||
#define XO_TABLE 0x00000002
|
||||
#define XO_TO_MONO 0x00000004
|
||||
|
||||
#define XO_SRCPALETTE 1
|
||||
#define XO_DESTPALETTE 2
|
||||
#define XO_DESTDCPALETTE 3
|
||||
|
||||
/* EngCreateBitmap format types */
|
||||
enum _BMF_TYPES
|
||||
{
|
||||
|
@ -67,6 +78,24 @@ enum _BMF_TYPES
|
|||
#define BMF_USERMEM 0x00000008
|
||||
#define BMF_KMSECTION 0x00000010
|
||||
|
||||
#define DC_TRIVIAL 0
|
||||
#define DC_RECT 1
|
||||
#define DC_COMPLEX 3
|
||||
|
||||
#define FC_RECT 1
|
||||
#define FC_RECT4 2
|
||||
#define FC_COMPLEX 3
|
||||
|
||||
#define TC_RECTANGLES 0
|
||||
#define TC_PATHOBJ 2
|
||||
|
||||
#define OC_BANK_CLIP 1
|
||||
|
||||
#define CT_RECTANGLES 0L
|
||||
|
||||
#define CD_LEFTWARDS 1L
|
||||
#define CD_UPWARDS 2L
|
||||
|
||||
/* Options for CLIPOBJ_cEnumStart BuildOrder field */
|
||||
enum _CD_ORDERS
|
||||
{
|
||||
|
@ -167,7 +196,78 @@ enum _GLYPH_MODE
|
|||
FO_GLYPHBITS,
|
||||
FO_PATHOBJ
|
||||
};
|
||||
|
||||
|
||||
// Allowed values for GDIINFO.ulPrimaryOrder.
|
||||
|
||||
#define PRIMARY_ORDER_ABC 0
|
||||
#define PRIMARY_ORDER_ACB 1
|
||||
#define PRIMARY_ORDER_BAC 2
|
||||
#define PRIMARY_ORDER_BCA 3
|
||||
#define PRIMARY_ORDER_CBA 4
|
||||
#define PRIMARY_ORDER_CAB 5
|
||||
|
||||
// Allowed values for GDIINFO.ulHTPatternSize.
|
||||
|
||||
#define HT_PATSIZE_2x2 0
|
||||
#define HT_PATSIZE_2x2_M 1
|
||||
#define HT_PATSIZE_4x4 2
|
||||
#define HT_PATSIZE_4x4_M 3
|
||||
#define HT_PATSIZE_6x6 4
|
||||
#define HT_PATSIZE_6x6_M 5
|
||||
#define HT_PATSIZE_8x8 6
|
||||
#define HT_PATSIZE_8x8_M 7
|
||||
#define HT_PATSIZE_10x10 8
|
||||
#define HT_PATSIZE_10x10_M 9
|
||||
#define HT_PATSIZE_12x12 10
|
||||
#define HT_PATSIZE_12x12_M 11
|
||||
#define HT_PATSIZE_14x14 12
|
||||
#define HT_PATSIZE_14x14_M 13
|
||||
#define HT_PATSIZE_16x16 14
|
||||
#define HT_PATSIZE_16x16_M 15
|
||||
#define HT_PATSIZE_MAX_INDEX HT_PATSIZE_16x16_M
|
||||
#define HT_PATSIZE_DEFAULT HT_PATSIZE_4x4_M
|
||||
|
||||
// Allowed values for GDIINFO.ulHTOutputFormat.
|
||||
|
||||
#define HT_FORMAT_1BPP 0
|
||||
#define HT_FORMAT_4BPP 2
|
||||
#define HT_FORMAT_4BPP_IRGB 3
|
||||
#define HT_FORMAT_8BPP 4
|
||||
#define HT_FORMAT_16BPP 5
|
||||
#define HT_FORMAT_24BPP 6
|
||||
#define HT_FORMAT_32BPP 7
|
||||
|
||||
// Allowed values for GDIINFO.flHTFlags.
|
||||
|
||||
#define HT_FLAG_SQUARE_DEVICE_PEL 0x00000001
|
||||
#define HT_FLAG_HAS_BLACK_DYE 0x00000002
|
||||
#define HT_FLAG_ADDITIVE_PRIMS 0x00000004
|
||||
#define HT_FLAG_OUTPUT_CMY 0x00000100
|
||||
|
||||
#define GCAPS_BEZIERS 0x00000001
|
||||
#define GCAPS_GEOMETRICWIDE 0x00000002
|
||||
#define GCAPS_ALTERNATEFILL 0x00000004
|
||||
#define GCAPS_WINDINGFILL 0x00000008
|
||||
#define GCAPS_HALFTONE 0x00000010
|
||||
#define GCAPS_COLOR_DITHER 0x00000020
|
||||
#define GCAPS_HORIZSTRIKE 0x00000040
|
||||
#define GCAPS_VERTSTRIKE 0x00000080
|
||||
#define GCAPS_OPAQUERECT 0x00000100
|
||||
#define GCAPS_VECTORFONT 0x00000200
|
||||
#define GCAPS_MONO_DITHER 0x00000400
|
||||
#define GCAPS_ASYNCCHANGE 0x00000800
|
||||
#define GCAPS_ASYNCMOVE 0x00001000
|
||||
#define GCAPS_DONTJOURNAL 0x00002000
|
||||
#define GCAPS_DIRECTDRAW 0x00004000
|
||||
#define GCAPS_ARBRUSHOPAQUE 0x00008000
|
||||
#define GCAPS_PANNING 0x00010000
|
||||
#define GCAPS_HIGHRESTEXT 0x00040000
|
||||
#define GCAPS_PALMANAGED 0x00080000
|
||||
#define GCAPS_DITHERONREALIZE 0x00200000
|
||||
#define GCAPS_NO64BITMEMACCESS 0x00400000
|
||||
#define GCAPS_FORCEDITHER 0x00800000
|
||||
#define GCAPS_GRAY16 0x01000000
|
||||
|
||||
/* EngAssocateSurface hook flags */
|
||||
#define HOOK_BITBLT 0x00000001
|
||||
#define HOOK_STRETCHBLT 0x00000002
|
||||
|
@ -310,6 +410,7 @@ typedef HANDLE HSURF;
|
|||
typedef HANDLE DHPDEV;
|
||||
typedef HANDLE DHSURF;
|
||||
typedef ULONG (*PFN)(VOID);
|
||||
typedef ULONG IDENT;
|
||||
|
||||
typedef struct _DRVFN
|
||||
{
|
||||
|
@ -865,7 +966,6 @@ EngAcquireSemaphore
|
|||
*/
|
||||
|
||||
/* FIXME: find correct defines for following symbols */
|
||||
#define ALLOC_TAG 1
|
||||
#define FL_ZERO_MEMORY 1
|
||||
|
||||
PVOID APIENTRY EngAllocMem(ULONG Flags,
|
||||
|
@ -926,6 +1026,15 @@ VOID APIENTRY EngDebugPrint(PCHAR StandardPrefix,
|
|||
|
||||
HANDLE STDCALL EngLoadImage(LPWSTR DriverName);
|
||||
|
||||
DWORD APIENTRY EngDeviceIoControl(
|
||||
HANDLE hDevice,
|
||||
DWORD dwIoControlCode,
|
||||
LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize,
|
||||
LPVOID lpOutBuffer,
|
||||
DWORD nOutBufferSize,
|
||||
DWORD *lpBytesReturned);
|
||||
|
||||
/*
|
||||
EngDeleteClip
|
||||
EngDeleteDriverObj
|
||||
|
@ -935,7 +1044,6 @@ EngDeletePath
|
|||
EngDeleteSemaphore
|
||||
EngDeleteSurface
|
||||
EngDeleteWnd
|
||||
EngDeviceIoControl
|
||||
EngEnumForms
|
||||
EngEraseSurface
|
||||
EngFillPath
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: loader.c,v 1.48 2000/02/27 18:01:44 ekohl Exp $
|
||||
/* $Id: loader.c,v 1.49 2000/03/17 21:02:56 jfilby Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -206,7 +206,7 @@ VOID LdrLoadAutoConfigDrivers (VOID)
|
|||
/*
|
||||
* VGA Miniport driver
|
||||
*/
|
||||
LdrLoadAutoConfigDriver( L"vgamp.sys" );
|
||||
// LdrLoadAutoConfigDriver( L"vgamp.sys" ); moving to win32k
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntoskrnl.def,v 1.57 2000/03/11 00:51:36 ea Exp $
|
||||
; $Id: ntoskrnl.def,v 1.58 2000/03/17 21:02:56 jfilby Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
|
@ -167,6 +167,7 @@ FsRtlUninitializeOplock@4
|
|||
IoAllocateIrp@8
|
||||
IoAllocateController
|
||||
IoAttachDeviceToDeviceStack
|
||||
IoBuildDeviceIoControlRequest
|
||||
IoBuildSynchronousFsdRequest
|
||||
IoCallDriver@8
|
||||
IoCompleteRequest@8
|
||||
|
@ -282,6 +283,7 @@ NtUnlockFile@20
|
|||
;NtVdmControl@8 <--- ?
|
||||
NtWaitForSingleObject@12
|
||||
NtWriteFile@36
|
||||
ObReferenceObjectByHandle
|
||||
PoQueryPowerSequence@0
|
||||
PoRequestPowerChange@12
|
||||
PoSetDeviceIdleDetection@8
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
; $Id: ntoskrnl.edf,v 1.44 2000/03/11 00:51:36 ea Exp $
|
||||
; $Id: ntoskrnl.edf,v 1.45 2000/03/17 21:02:56 jfilby Exp $
|
||||
;
|
||||
; reactos/ntoskrnl/ntoskrnl.def
|
||||
;
|
||||
|
@ -167,6 +167,7 @@ FsRtlUninitializeOplock=FsRtlUninitializeOplock@4
|
|||
IoAllocateIrp=IoAllocateIrp@8
|
||||
IoAllocateController
|
||||
IoAttachDeviceToDeviceStack
|
||||
IoBuildDeviceIoControlRequest
|
||||
IoBuildSynchronousFsdRequest
|
||||
IoCallDriver=IoCallDriver@8
|
||||
IoCompleteRequest=IoCompleteRequest@8
|
||||
|
@ -282,6 +283,7 @@ NtUnlockFile=NtUnlockFile@20
|
|||
;NtVdmControl@8 <--- ?
|
||||
NtWaitForSingleObject=NtWaitForSingleObject@12
|
||||
NtWriteFile=NtWriteFile@36
|
||||
ObReferenceObjectByHandle
|
||||
PoQueryPowerSequence=PoQueryPowerSequence@0
|
||||
PoRequestPowerChange=PoRequestPowerChange@12
|
||||
PoSetDeviceIdleDetection=PoSetDeviceIdleDetection@8
|
||||
|
|
|
@ -23,15 +23,14 @@ DWORD APIENTRY EngDeviceIoControl(
|
|||
NTSTATUS Status;
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
PDEVICE_OBJECT theDevice;
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
|
||||
ObReferenceObjectByHandle(hDevice, GENERIC_ALL, NULL, UserMode,
|
||||
(PVOID *)&theDevice, NULL);
|
||||
DriverObject = hDevice;
|
||||
|
||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||
|
||||
Irp = IoBuildDeviceIoControlRequest(dwIoControlCode,
|
||||
theDevice,
|
||||
DriverObject->DeviceObject,
|
||||
lpInBuffer,
|
||||
nInBufferSize,
|
||||
lpOutBuffer,
|
||||
|
@ -40,7 +39,7 @@ DWORD APIENTRY EngDeviceIoControl(
|
|||
&Event,
|
||||
&Iosb);
|
||||
|
||||
Status = IoCallDriver(theDevice, Irp);
|
||||
Status = IoCallDriver(DriverObject->DeviceObject, Irp);
|
||||
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include <ddk/winddi.h>
|
||||
|
||||
HANDLE __cdecl LdrLoadModule (LPWSTR);
|
||||
// HANDLE __cdecl LdrLoadModule (LPWSTR);
|
||||
|
||||
HANDLE
|
||||
STDCALL
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: driver.c,v 1.10 2000/03/10 12:39:53 jfilby Exp $
|
||||
/* $Id: driver.c,v 1.11 2000/03/17 21:02:59 jfilby Exp $
|
||||
*
|
||||
* GDI Driver support routines
|
||||
* (mostly swiped from Wine)
|
||||
|
@ -14,6 +14,7 @@
|
|||
#include <wchar.h>
|
||||
#include <internal/module.h>
|
||||
#include <ddk/winddi.h>
|
||||
#include <ddk/ntddvid.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -63,7 +64,6 @@ BOOL DRIVER_RegisterDriver(LPCWSTR Name, PGD_ENABLEDRIVER EnableDriver)
|
|||
PGD_ENABLEDRIVER DRIVER_FindDDIDriver(LPCWSTR Name)
|
||||
{
|
||||
UNICODE_STRING DriverNameW;
|
||||
NTSTATUS Status;
|
||||
PMODULE_OBJECT ModuleObject;
|
||||
GRAPHICS_DRIVER *Driver = DriverList;
|
||||
|
||||
|
@ -162,14 +162,27 @@ BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
HANDLE DRIVER_FindMPDriver(LPCWSTR Name)
|
||||
typedef VP_STATUS (*PMP_DRIVERENTRY)(PVOID, PVOID);
|
||||
|
||||
HANDLE DRIVER_FindMPDriver(LPCWSTR Name)
|
||||
{
|
||||
UNICODE_STRING DriverNameW;
|
||||
PMODULE_OBJECT ModuleObject;
|
||||
|
||||
PWSTR lName;
|
||||
HANDLE DriverHandle;
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING DeviceName;
|
||||
HANDLE DriverHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
|
||||
PDRIVER_OBJECT DriverObject;
|
||||
PMP_DRIVERENTRY PMP_DriverEntry;
|
||||
|
||||
/* Phase 1 */
|
||||
RtlInitUnicodeString (&DriverNameW, L"\\??\\C:\\reactos\\system32\\drivers\\vgamp.sys");
|
||||
ModuleObject = EngLoadImage(&DriverNameW);
|
||||
|
||||
/* Phase 2 */
|
||||
if (Name[0] != '\\')
|
||||
{
|
||||
lName = ExAllocatePool(NonPagedPool, wcslen(Name) * sizeof(WCHAR) +
|
||||
|
@ -191,36 +204,21 @@ HANDLE DRIVER_FindMPDriver(LPCWSTR Name)
|
|||
wcscpy(lName, Name);
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&DeviceName, lName);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&DeviceName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenFile(&DriverHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
NULL,
|
||||
0,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("Failed to open display device\n");
|
||||
DbgPrint("%08lx\n", Status);
|
||||
if (Name[0] != '\\')
|
||||
{
|
||||
ExFreePool(lName);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/* Phase 3 */
|
||||
DriverObject = ExAllocatePool(NonPagedPool,sizeof(DRIVER_OBJECT));
|
||||
if (DriverObject == NULL)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
memset(DriverObject, 0, sizeof(DRIVER_OBJECT));
|
||||
|
||||
if (Name[0] != '\\')
|
||||
{
|
||||
ExFreePool(lName);
|
||||
}
|
||||
// We pass the DriverObject to the Miniport driver, which passes it to the VideoPort driver
|
||||
// The VideoPort driver then creates the Device Object
|
||||
|
||||
return DriverHandle;
|
||||
PMP_DriverEntry = ModuleObject->EntryPoint;
|
||||
PMP_DriverEntry(DriverObject, NULL);
|
||||
|
||||
return DriverObject;
|
||||
}
|
||||
|
||||
BOOL DRIVER_UnregisterDriver(LPCWSTR Name)
|
||||
|
@ -299,4 +297,3 @@ INT DRIVER_UnreferenceDriver (LPCWSTR Name)
|
|||
|
||||
return GenericDriver ? --GenericDriver->ReferenceCount : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dc.c,v 1.12 2000/03/08 21:23:14 jfilby Exp $
|
||||
/* $Id: dc.c,v 1.13 2000/03/17 21:02:59 jfilby Exp $
|
||||
*
|
||||
* DC.C - Device context functions
|
||||
*
|
||||
|
@ -166,7 +166,7 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
|||
PDC NewDC;
|
||||
HDC hDC = NULL;
|
||||
DRVENABLEDATA DED;
|
||||
|
||||
|
||||
/* Check for existing DC object */
|
||||
if ((NewDC = DC_FindOpenDC(Driver)) != NULL)
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
|||
DbgPrint("FindMPDriver failed\n");
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
|
||||
/* Get the DDI driver's entry point */
|
||||
/* FIXME: Retrieve DDI driver name from registry */
|
||||
if ((GDEnableDriver = DRIVER_FindDDIDriver(L"\\??\\C:\\reactos\\system32\\drivers\\vgaddi.dll")) == NULL)
|
||||
|
@ -194,9 +194,10 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
|||
DbgPrint("FindDDIDriver failed\n");
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
|
||||
/* Call DDI driver's EnableDriver function */
|
||||
RtlZeroMemory(&DED, sizeof(DED));
|
||||
|
||||
if (!GDEnableDriver(DDI_DRIVER_VERSION, sizeof(DED), &DED))
|
||||
{
|
||||
DbgPrint("DrvEnableDriver failed\n");
|
||||
|
@ -209,7 +210,7 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
|||
DbgPrint("BuildDDIFunctions failed\n");
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
|
||||
/* Allocate a phyical device handle from the driver */
|
||||
if (Device != NULL)
|
||||
{
|
||||
|
@ -226,6 +227,7 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
|||
NewDC->DMW.dmPelsHeight = 480;
|
||||
NewDC->DMW.dmDisplayFlags = 0;
|
||||
NewDC->DMW.dmDisplayFrequency = 0;
|
||||
|
||||
NewDC->PDev = NewDC->DriverFunctions.EnablePDev(&NewDC->DMW,
|
||||
L"",
|
||||
HS_DDI_MAX,
|
||||
|
@ -242,18 +244,18 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
|||
DbgPrint("DrvEnablePDEV failed\n");
|
||||
goto Failure;
|
||||
}
|
||||
|
||||
|
||||
/* Complete initialization of the physical device */
|
||||
NewDC->DriverFunctions.CompletePDev(NewDC->PDev, NewDC);
|
||||
|
||||
DRIVER_ReferenceDriver (Driver);
|
||||
|
||||
|
||||
/* Enable the drawing surface */
|
||||
NewDC->Surface = NewDC->DriverFunctions.EnableSurface(NewDC->PDev);
|
||||
|
||||
/* Initialize the DC state */
|
||||
DC_InitDC(NewDC);
|
||||
|
||||
|
||||
return DC_PtrToHandle(NewDC);
|
||||
|
||||
Failure:
|
||||
|
|
Loading…
Reference in a new issue