diff --git a/reactos/drivers/video/displays/framebuf/.cvsignore b/reactos/drivers/video/displays/framebuf/.cvsignore new file mode 100644 index 00000000000..111e4dd985e --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/.cvsignore @@ -0,0 +1,7 @@ +*.coff +*.sym +*.o +*.dll +*.map +*.tmp +.*.d diff --git a/reactos/drivers/video/displays/framebuf/enable.c b/reactos/drivers/video/displays/framebuf/enable.c new file mode 100644 index 00000000000..3c8a24a9d80 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/enable.c @@ -0,0 +1,163 @@ +/* + * ReactOS Generic Framebuffer display driver + * + * Copyright (C) 2004 Filip Navara + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "framebuf.h" + +static DRVFN DrvFunctionTable[] = +{ + {INDEX_DrvEnablePDEV, (PFN)DrvEnablePDEV}, + {INDEX_DrvCompletePDEV, (PFN)DrvCompletePDEV}, + {INDEX_DrvDisablePDEV, (PFN)DrvDisablePDEV}, + {INDEX_DrvEnableSurface, (PFN)DrvEnableSurface}, + {INDEX_DrvDisableSurface, (PFN)DrvDisableSurface}, + {INDEX_DrvAssertMode, (PFN)DrvAssertMode}, + {INDEX_DrvGetModes, (PFN)DrvGetModes}, + {INDEX_DrvSetPalette, (PFN)DrvSetPalette}, + {INDEX_DrvSetPointerShape, (PFN)DrvSetPointerShape}, + {INDEX_DrvMovePointer, (PFN)DrvMovePointer}, +}; + +/* + * DrvEnableDriver + * + * Initial driver entry point exported by the driver DLL. It fills in a + * DRVENABLEDATA structure with the driver's DDI version number and the + * calling addresses of all DDI functions supported by the driver. + * + * Status + * @implemented + */ + +BOOL DDKAPI +DrvEnableDriver( + ULONG iEngineVersion, + ULONG cj, + PDRVENABLEDATA pded) +{ + if (cj >= sizeof(DRVENABLEDATA)) + { + pded->c = sizeof(DrvFunctionTable) / sizeof(DRVFN); + pded->pdrvfn = DrvFunctionTable; + pded->iDriverVersion = DDI_DRIVER_VERSION_NT5; + return TRUE; + } + else + { + return FALSE; + } +} + +/* + * DrvEnablePDEV + * + * Returns a description of the physical device's characteristics to GDI. + * + * Status + * @implemented + */ + +DHPDEV DDKAPI +DrvEnablePDEV( + IN DEVMODEW *pdm, + IN LPWSTR pwszLogAddress, + IN ULONG cPat, + OUT HSURF *phsurfPatterns, + IN ULONG cjCaps, + OUT ULONG *pdevcaps, + IN ULONG cjDevInfo, + OUT DEVINFO *pdi, + IN HDEV hdev, + IN LPWSTR pwszDeviceName, + IN HANDLE hDriver) +{ + PPDEV ppdev; + GDIINFO GdiInfo; + DEVINFO DevInfo; + + ppdev = EngAllocMem(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG); + if (ppdev == NULL) + { + return NULL; + } + + ppdev->hDriver = hDriver; + + if (!IntInitScreenInfo(ppdev, pdm, &GdiInfo, &DevInfo)) + { + EngFreeMem(ppdev); + return NULL; + } + + if (!IntInitDefaultPalette(ppdev, &DevInfo)) + { + EngFreeMem(ppdev); + return NULL; + } + + memcpy(pdi, &DevInfo, min(sizeof(DEVINFO), cjDevInfo)); + memcpy(pdevcaps, &GdiInfo, min(sizeof(GDIINFO), cjCaps)); + + return (DHPDEV)ppdev; +} + +/* + * DrvCompletePDEV + * + * Stores the GDI handle (hdev) of the physical device in dhpdev. The driver + * should retain this handle for use when calling GDI services. + * + * Status + * @implemented + */ + +VOID DDKAPI +DrvCompletePDEV( + IN DHPDEV dhpdev, + IN HDEV hdev) +{ + ((PPDEV)dhpdev)->hDevEng = hdev; +} + +/* + * DrvDisablePDEV + * + * Release the resources allocated in DrvEnablePDEV. If a surface has been + * enabled DrvDisableSurface will have already been called. + * + * Status + * @implemented + */ + +VOID DDKAPI +DrvDisablePDEV( + IN DHPDEV dhpdev) +{ + if (((PPDEV)dhpdev)->DefaultPalette) + { + EngDeletePalette(((PPDEV)dhpdev)->DefaultPalette); + } + + if (((PPDEV)dhpdev)->PaletteEntries != NULL) + { + EngFreeMem(((PPDEV)dhpdev)->PaletteEntries); + } + + EngFreeMem(dhpdev); +} diff --git a/reactos/drivers/video/displays/framebuf/framebuf.def b/reactos/drivers/video/displays/framebuf/framebuf.def new file mode 100644 index 00000000000..3ab97ffa6b8 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/framebuf.def @@ -0,0 +1,3 @@ +LIBRARY framebuf.dll +EXPORTS +DrvEnableDriver@12 diff --git a/reactos/drivers/video/displays/framebuf/framebuf.edf b/reactos/drivers/video/displays/framebuf/framebuf.edf new file mode 100644 index 00000000000..6fd6bc1fad6 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/framebuf.edf @@ -0,0 +1,3 @@ +LIBRARY framebuf.dll +EXPORTS +DrvEnableDriver=DrvEnableDriver@12 diff --git a/reactos/drivers/video/displays/framebuf/framebuf.h b/reactos/drivers/video/displays/framebuf/framebuf.h new file mode 100644 index 00000000000..41353de0ef5 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/framebuf.h @@ -0,0 +1,140 @@ +/* + * ReactOS Generic Framebuffer display driver + * + * Copyright (C) 2004 Filip Navara + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef FRAMEBUF_H +#define FRAMEBUF_H + +#include +#include +#include +#include + +typedef struct _PDEV +{ + HANDLE hDriver; + HDEV hDevEng; + HSURF hSurfEng; + ULONG ModeIndex; + ULONG ScreenWidth; + ULONG ScreenHeight; + ULONG ScreenDelta; + BYTE BitsPerPixel; + ULONG RedMask; + ULONG GreenMask; + ULONG BlueMask; + BYTE PaletteShift; + PVOID ScreenPtr; + HPALETTE DefaultPalette; + PALETTEENTRY *PaletteEntries; +} PDEV, *PPDEV; + +#define DEVICE_NAME L"framebuf" +#define ALLOC_TAG TAG('F','B','U','F') + +DHPDEV STDCALL +DrvEnablePDEV( + IN DEVMODEW *pdm, + IN LPWSTR pwszLogAddress, + IN ULONG cPat, + OUT HSURF *phsurfPatterns, + IN ULONG cjCaps, + OUT ULONG *pdevcaps, + IN ULONG cjDevInfo, + OUT DEVINFO *pdi, + IN HDEV hdev, + IN LPWSTR pwszDeviceName, + IN HANDLE hDriver); + +VOID STDCALL +DrvCompletePDEV( + IN DHPDEV dhpdev, + IN HDEV hdev); + +VOID STDCALL +DrvDisablePDEV( + IN DHPDEV dhpdev); + +HSURF STDCALL +DrvEnableSurface( + IN DHPDEV dhpdev); + +VOID STDCALL +DrvDisableSurface( + IN DHPDEV dhpdev); + +BOOL STDCALL +DrvAssertMode( + IN DHPDEV dhpdev, + IN BOOL bEnable); + +ULONG STDCALL +DrvGetModes( + IN HANDLE hDriver, + IN ULONG cjSize, + OUT DEVMODEW *pdm); + +BOOL STDCALL +DrvSetPalette( + IN DHPDEV dhpdev, + IN PALOBJ *ppalo, + IN FLONG fl, + IN ULONG iStart, + IN ULONG cColors); + +ULONG STDCALL +DrvSetPointerShape( + IN SURFOBJ *pso, + IN SURFOBJ *psoMask, + IN SURFOBJ *psoColor, + IN XLATEOBJ *pxlo, + IN LONG xHot, + IN LONG yHot, + IN LONG x, + IN LONG y, + IN RECTL *prcl, + IN FLONG fl); + +VOID STDCALL +DrvMovePointer( + IN SURFOBJ *pso, + IN LONG x, + IN LONG y, + IN RECTL *prcl); + +BOOL FASTCALL +IntInitScreenInfo( + PPDEV ppdev, + LPDEVMODEW pDevMode, + PGDIINFO pGdiInfo, + PDEVINFO pDevInfo); + +BOOL FASTCALL +IntInitDefaultPalette( + PPDEV ppdev, + PDEVINFO pDevInfo); + +BOOL DDKAPI +IntSetPalette( + IN DHPDEV dhpdev, + IN PPALETTEENTRY ppalent, + IN ULONG iStart, + IN ULONG cColors); + +#endif /* FRAMEBUF_H */ diff --git a/reactos/drivers/video/displays/framebuf/framebuf.rc b/reactos/drivers/video/displays/framebuf/framebuf.rc new file mode 100644 index 00000000000..9ae577ef842 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/framebuf.rc @@ -0,0 +1,38 @@ +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "Framebuffer Display Driver\0" + VALUE "FileVersion", RES_STR_FILE_VERSION + VALUE "InternalName", "framebuf\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "framebuf.dll\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/reactos/drivers/video/displays/framebuf/makefile b/reactos/drivers/video/displays/framebuf/makefile new file mode 100644 index 00000000000..395791cf165 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/makefile @@ -0,0 +1,28 @@ +# $Id: makefile,v 1.1 2004/01/13 17:18:33 navaraf Exp $ + +PATH_TO_TOP = ../../../.. + +TARGET_BASE = 0x70000000 + +TARGET_TYPE = gdi_driver + +TARGET_NAME = framebuf + +TARGET_CFLAGS = -Wall -Werror -D__USE_W32API + +TARGET_OBJECTS = \ + enable.o \ + palette.o \ + pointer.o \ + screen.o \ + surface.o + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# Automatic dependency tracking +DEP_OBJECTS = $(TARGET_OBJECTS) +include $(PATH_TO_TOP)/tools/depend.mk + +# EOF diff --git a/reactos/drivers/video/displays/framebuf/palette.c b/reactos/drivers/video/displays/framebuf/palette.c new file mode 100644 index 00000000000..b0546219e3c --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/palette.c @@ -0,0 +1,198 @@ +/* + * ReactOS Generic Framebuffer display driver + * + * Copyright (C) 2004 Filip Navara + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "framebuf.h" + +/* + * Standard color that must be in palette, because they're used for + * drawing window borders and other GUI elements. + */ + +const PALETTEENTRY BASEPALETTE[20] = +{ + { 0x00, 0x00, 0x00, 0x00 }, + { 0x80, 0x00, 0x00, 0x00 }, + { 0x00, 0x80, 0x00, 0x00 }, + { 0x80, 0x80, 0x00, 0x00 }, + { 0x00, 0x00, 0x80, 0x00 }, + { 0x80, 0x00, 0x80, 0x00 }, + { 0x00, 0x80, 0x80, 0x00 }, + { 0xC0, 0xC0, 0xC0, 0x00 }, + { 0xC0, 0xDC, 0xC0, 0x00 }, + { 0xA6, 0xCA, 0xF0, 0x00 }, + { 0xFF, 0xFB, 0xF0, 0x00 }, + { 0xA0, 0xA0, 0xA4, 0x00 }, + { 0x80, 0x80, 0x80, 0x00 }, + { 0xFF, 0x00, 0x00, 0x00 }, + { 0x00, 0xFF, 0x00, 0x00 }, + { 0xFF, 0xFF, 0x00, 0x00 }, + { 0x00, 0x00, 0xFF, 0x00 }, + { 0xFF, 0x00, 0xFF, 0x00 }, + { 0x00, 0xFF, 0xFF, 0x00 }, + { 0xFF, 0xFF, 0xFF, 0x00 }, +}; + +/* + * IntInitDefaultPalette + * + * Initializes default palette for PDEV and fill it with the colors specified + * by the GDI standard. + */ + +BOOL FASTCALL +IntInitDefaultPalette( + PPDEV ppdev, + PDEVINFO pDevInfo) +{ + ULONG ColorLoop; + PPALETTEENTRY PaletteEntryPtr; + BYTE Red = 0, Green = 0, Blue = 0; + + if (ppdev->BitsPerPixel > 8) + { + ppdev->DefaultPalette = pDevInfo->hpalDefault = + EngCreatePalette(PAL_BITFIELDS, 0, NULL, + ppdev->RedMask, ppdev->GreenMask, ppdev->BlueMask); + } + else + { + ppdev->PaletteEntries = EngAllocMem(FL_ZERO_MEMORY, + sizeof(PALETTEENTRY) << 8, ALLOC_TAG); + if (ppdev->PaletteEntries == NULL) + { + return FALSE; + } + + for (ColorLoop = 256, PaletteEntryPtr = ppdev->PaletteEntries; + ColorLoop != 0; + ColorLoop--, PaletteEntryPtr++) + { + PaletteEntryPtr->peRed = Red; + PaletteEntryPtr->peGreen = Green; + PaletteEntryPtr->peBlue = Blue; + PaletteEntryPtr->peFlags = 0; + + if (!(Red += 32)) + if (!(Green += 32)) + Blue += 64; + } + + memcpy(ppdev->PaletteEntries, BASEPALETTE, 10 * sizeof(PALETTEENTRY)); + memcpy(ppdev->PaletteEntries + 246, BASEPALETTE + 10, 10 * sizeof(PALETTEENTRY)); + + ppdev->DefaultPalette = pDevInfo->hpalDefault = + EngCreatePalette(PAL_INDEXED, 256, (PULONG)ppdev->PaletteEntries, 0, 0, 0); + } + + return ppdev->DefaultPalette != NULL; +} + +/* + * IntSetPalette + * + * Requests that the driver realize the palette for a specified device. The + * driver sets the hardware palette to match the entries in the given palette + * as closely as possible. + */ + +BOOL DDKAPI +IntSetPalette( + IN DHPDEV dhpdev, + IN PPALETTEENTRY ppalent, + IN ULONG iStart, + IN ULONG cColors) +{ + PVIDEO_CLUT pClut; + ULONG ClutSize; + + ClutSize = sizeof(VIDEO_CLUT) + (cColors * sizeof(ULONG)); + pClut = EngAllocMem(0, ClutSize, ALLOC_TAG); + pClut->FirstEntry = iStart; + pClut->NumEntries = cColors; + memcpy(&pClut->LookupTable[0].RgbLong, ppalent, sizeof(ULONG) * cColors); + + if (((PPDEV)dhpdev)->PaletteShift) + { + while (cColors--) + { + pClut->LookupTable[cColors].RgbArray.Red >>= ((PPDEV)dhpdev)->PaletteShift; + pClut->LookupTable[cColors].RgbArray.Green >>= ((PPDEV)dhpdev)->PaletteShift; + pClut->LookupTable[cColors].RgbArray.Blue >>= ((PPDEV)dhpdev)->PaletteShift; + pClut->LookupTable[cColors].RgbArray.Unused = 0; + } + } + else + { + while (cColors--) + { + pClut->LookupTable[cColors].RgbArray.Unused = 0; + } + } + + /* + * Set the palette registers. + */ + + if (EngDeviceIoControl(((PPDEV)dhpdev)->hDriver, IOCTL_VIDEO_SET_COLOR_REGISTERS, + pClut, ClutSize, NULL, 0, &cColors)) + { + EngFreeMem(pClut); + return FALSE; + } + + EngFreeMem(pClut); + return TRUE; +} + +/* + * DrvSetPalette + * + * Requests that the driver realize the palette for a specified device. The + * driver sets the hardware palette to match the entries in the given palette + * as closely as possible. + * + * Status + * @implemented + */ + +BOOL DDKAPI +DrvSetPalette( + IN DHPDEV dhpdev, + IN PALOBJ *ppalo, + IN FLONG fl, + IN ULONG iStart, + IN ULONG cColors) +{ + PPALETTEENTRY PaletteEntries; + + PaletteEntries = EngAllocMem(0, cColors * sizeof(ULONG), ALLOC_TAG); + if (PaletteEntries == NULL) + { + return FALSE; + } + + if (PALOBJ_cGetColors(ppalo, iStart, cColors, (PULONG)PaletteEntries) != + cColors) + { + return FALSE; + } + + return IntSetPalette(dhpdev, PaletteEntries, iStart, cColors); +} diff --git a/reactos/drivers/video/displays/framebuf/pointer.c b/reactos/drivers/video/displays/framebuf/pointer.c new file mode 100644 index 00000000000..61078ffde5d --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/pointer.c @@ -0,0 +1,66 @@ +/* + * ReactOS Generic Framebuffer display driver + * + * Copyright (C) 2004 Filip Navara + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "framebuf.h" + +/* + * DrvSetPointerShape + * + * Sets the new pointer shape. + * + * Status + * @unimplemented + */ + +ULONG DDKAPI +DrvSetPointerShape( + IN SURFOBJ *pso, + IN SURFOBJ *psoMask, + IN SURFOBJ *psoColor, + IN XLATEOBJ *pxlo, + IN LONG xHot, + IN LONG yHot, + IN LONG x, + IN LONG y, + IN RECTL *prcl, + IN FLONG fl) +{ + return SPS_DECLINE; +} + +/* + * DrvMovePointer + * + * Moves the pointer to a new position and ensures that GDI does not interfere + * with the display of the pointer. + * + * Status + * @unimplemented + */ + +VOID DDKAPI +DrvMovePointer( + IN SURFOBJ *pso, + IN LONG x, + IN LONG y, + IN RECTL *prcl) +{ + +} diff --git a/reactos/drivers/video/displays/framebuf/screen.c b/reactos/drivers/video/displays/framebuf/screen.c new file mode 100644 index 00000000000..530936e5c3a --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/screen.c @@ -0,0 +1,407 @@ +/* + * ReactOS Generic Framebuffer display driver + * + * Copyright (C) 2004 Filip Navara + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "framebuf.h" + +/* + * GetAvailableModes + * + * Calls the miniport to get the list of modes supported by the kernel driver, + * and returns the list of modes supported by the display driver. + */ + +DWORD FASTCALL +GetAvailableModes( + HANDLE hDriver, + PVIDEO_MODE_INFORMATION *ModeInfo, + DWORD *ModeInfoSize) +{ + ULONG ulTemp; + VIDEO_NUM_MODES Modes; + PVIDEO_MODE_INFORMATION ModeInfoPtr; + + /* + * Get the number of modes supported by the mini-port + */ + + if (EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES, NULL, + 0, &Modes, sizeof(VIDEO_NUM_MODES), &ulTemp)) + { + return 0; + } + + *ModeInfoSize = Modes.ModeInformationLength; + + /* + * Allocate the buffer for the miniport to write the modes in. + */ + + *ModeInfo = (PVIDEO_MODE_INFORMATION)EngAllocMem(0, Modes.NumModes * + Modes.ModeInformationLength, ALLOC_TAG); + + if (*ModeInfo == NULL) + { + return 0; + } + + /* + * Ask the miniport to fill in the available modes. + */ + + if (EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_AVAIL_MODES, NULL, 0, + *ModeInfo, Modes.NumModes * Modes.ModeInformationLength, + &ulTemp)) + { + EngFreeMem(*ModeInfo); + *ModeInfo = (PVIDEO_MODE_INFORMATION)NULL; + return 0; + } + + /* + * Now see which of these modes are supported by the display driver. + * As an internal mechanism, set the length to 0 for the modes we + * DO NOT support. + */ + + ulTemp = Modes.NumModes; + ModeInfoPtr = *ModeInfo; + + /* + * Mode is rejected if it is not one plane, or not graphics, or is not + * one of 8, 16 or 32 bits per pel. + */ + + while (ulTemp--) + { + if ((ModeInfoPtr->NumberOfPlanes != 1 ) || + !(ModeInfoPtr->AttributeFlags & VIDEO_MODE_GRAPHICS) || + ((ModeInfoPtr->BitsPerPlane != 8) && + (ModeInfoPtr->BitsPerPlane != 16) && + (ModeInfoPtr->BitsPerPlane != 24) && + (ModeInfoPtr->BitsPerPlane != 32))) + { + ModeInfoPtr->Length = 0; + } + + ModeInfoPtr = (PVIDEO_MODE_INFORMATION) + (((PUCHAR)ModeInfoPtr) + Modes.ModeInformationLength); + } + + return Modes.NumModes; +} + +BOOL FASTCALL +IntInitScreenInfo( + PPDEV ppdev, + LPDEVMODEW pDevMode, + PGDIINFO pGdiInfo, + PDEVINFO pDevInfo) +{ + ULONG ModeCount; + ULONG ModeInfoSize; + PVIDEO_MODE_INFORMATION ModeInfo, ModeInfoPtr, SelectedMode = NULL; + VIDEO_COLOR_CAPABILITIES ColorCapabilities; + LOGFONTW SystemFont = {16, 7, 0, 0, 700, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_DONTCARE, L"System"}; + LOGFONTW AnsiVariableFont = {12, 9, 0, 0, 400, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_STROKE_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_DONTCARE, L"MS Sans Serif"}; + LOGFONTW AnsiFixedFont = {12, 9, 0, 0, 400, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_STROKE_PRECIS, PROOF_QUALITY, FIXED_PITCH | FF_DONTCARE, L"Courier"}; + ULONG Temp; + + /* + * Call miniport to get information about video modes. + */ + + ModeCount = GetAvailableModes(ppdev->hDriver, &ModeInfo, &ModeInfoSize); + if (ModeCount == 0) + { + return FALSE; + } + + /* + * Select the video mode depending on the info passed in pDevMode. + */ + + if (pDevMode->dmPelsWidth == 0 && pDevMode->dmPelsHeight == 0 && + pDevMode->dmBitsPerPel == 0 && pDevMode->dmDisplayFrequency == 0) + { + ModeInfoPtr = ModeInfo; + while (ModeCount-- > 0) + { + if (ModeInfoPtr->Length == 0) + { + continue; + } + SelectedMode = ModeInfoPtr; + break; + } + } + else + { + ModeInfoPtr = ModeInfo; + while (ModeCount-- > 0) + { + if (ModeInfoPtr->Length == 0) + { + continue; + } + if (pDevMode->dmPelsWidth == ModeInfoPtr->VisScreenWidth && + pDevMode->dmPelsHeight == ModeInfoPtr->VisScreenHeight && + pDevMode->dmBitsPerPel == (ModeInfoPtr->BitsPerPlane * + ModeInfoPtr->NumberOfPlanes) && + pDevMode->dmDisplayFrequency == ModeInfoPtr->Frequency) + { + SelectedMode = ModeInfoPtr; + break; + } + } + } + + if (SelectedMode == NULL) + { + EngFreeMem(ModeInfo); + return FALSE; + } + + /* + * Fill in the GDIINFO data structure with the information returned from + * the kernel driver. + */ + + ppdev->ModeIndex = SelectedMode->ModeIndex; + ppdev->ScreenWidth = SelectedMode->VisScreenWidth; + ppdev->ScreenHeight = SelectedMode->VisScreenHeight; + ppdev->ScreenDelta = SelectedMode->ScreenStride; + ppdev->BitsPerPixel = SelectedMode->BitsPerPlane * SelectedMode->NumberOfPlanes; + + ppdev->RedMask = SelectedMode->RedMask; + ppdev->GreenMask = SelectedMode->GreenMask; + ppdev->BlueMask = SelectedMode->BlueMask; + + pGdiInfo->ulVersion = GDI_DRIVER_VERSION; + pGdiInfo->ulTechnology = DT_RASDISPLAY; + pGdiInfo->ulHorzSize = SelectedMode->XMillimeter; + pGdiInfo->ulVertSize = SelectedMode->YMillimeter; + pGdiInfo->ulHorzRes = SelectedMode->VisScreenWidth; + pGdiInfo->ulVertRes = SelectedMode->VisScreenHeight; + pGdiInfo->ulPanningHorzRes = SelectedMode->VisScreenWidth; + pGdiInfo->ulPanningVertRes = SelectedMode->VisScreenHeight; + pGdiInfo->cBitsPixel = SelectedMode->BitsPerPlane; + pGdiInfo->cPlanes = SelectedMode->NumberOfPlanes; + pGdiInfo->ulVRefresh = SelectedMode->Frequency; + pGdiInfo->ulBltAlignment = 1; + pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels; + pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels; + pGdiInfo->flTextCaps = TC_RA_ABLE; + pGdiInfo->ulDACRed = SelectedMode->NumberRedBits; + pGdiInfo->ulDACGreen = SelectedMode->NumberGreenBits; + pGdiInfo->ulDACBlue = SelectedMode->NumberBlueBits; + pGdiInfo->ulAspectX = 0x24; + pGdiInfo->ulAspectY = 0x24; + pGdiInfo->ulAspectXY = 0x33; + pGdiInfo->xStyleStep = 1; + pGdiInfo->yStyleStep = 1; + pGdiInfo->denStyleStep = 3; + pGdiInfo->ptlPhysOffset.x = 0; + pGdiInfo->ptlPhysOffset.y = 0; + pGdiInfo->szlPhysSize.cx = 0; + pGdiInfo->szlPhysSize.cy = 0; + + /* + * Try to get the color info from the miniport. + */ + + if (!EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES, + NULL, 0, &ColorCapabilities, + sizeof(VIDEO_COLOR_CAPABILITIES), &Temp)) + { + pGdiInfo->ciDevice.Red.x = ColorCapabilities.RedChromaticity_x; + pGdiInfo->ciDevice.Red.y = ColorCapabilities.RedChromaticity_y; + pGdiInfo->ciDevice.Green.x = ColorCapabilities.GreenChromaticity_x; + pGdiInfo->ciDevice.Green.y = ColorCapabilities.GreenChromaticity_y; + pGdiInfo->ciDevice.Blue.x = ColorCapabilities.BlueChromaticity_x; + pGdiInfo->ciDevice.Blue.y = ColorCapabilities.BlueChromaticity_y; + pGdiInfo->ciDevice.AlignmentWhite.x = ColorCapabilities.WhiteChromaticity_x; + pGdiInfo->ciDevice.AlignmentWhite.y = ColorCapabilities.WhiteChromaticity_y; + pGdiInfo->ciDevice.AlignmentWhite.Y = ColorCapabilities.WhiteChromaticity_Y; + if (ColorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR) + { + pGdiInfo->ciDevice.RedGamma = ColorCapabilities.RedGamma; + pGdiInfo->ciDevice.GreenGamma = ColorCapabilities.GreenGamma; + pGdiInfo->ciDevice.BlueGamma = ColorCapabilities.BlueGamma; + } + else + { + pGdiInfo->ciDevice.RedGamma = ColorCapabilities.WhiteGamma; + pGdiInfo->ciDevice.GreenGamma = ColorCapabilities.WhiteGamma; + pGdiInfo->ciDevice.BlueGamma = ColorCapabilities.WhiteGamma; + } + } + else + { + pGdiInfo->ciDevice.Red.x = 6700; + pGdiInfo->ciDevice.Red.y = 3300; + pGdiInfo->ciDevice.Green.x = 2100; + pGdiInfo->ciDevice.Green.y = 7100; + pGdiInfo->ciDevice.Blue.x = 1400; + pGdiInfo->ciDevice.Blue.y = 800; + pGdiInfo->ciDevice.AlignmentWhite.x = 3127; + pGdiInfo->ciDevice.AlignmentWhite.y = 3290; + pGdiInfo->ciDevice.AlignmentWhite.Y = 0; + pGdiInfo->ciDevice.RedGamma = 20000; + pGdiInfo->ciDevice.GreenGamma = 20000; + pGdiInfo->ciDevice.BlueGamma = 20000; + } + + pGdiInfo->ciDevice.Red.Y = 0; + pGdiInfo->ciDevice.Green.Y = 0; + pGdiInfo->ciDevice.Blue.Y = 0; + pGdiInfo->ciDevice.Cyan.x = 0; + pGdiInfo->ciDevice.Cyan.y = 0; + pGdiInfo->ciDevice.Cyan.Y = 0; + pGdiInfo->ciDevice.Magenta.x = 0; + pGdiInfo->ciDevice.Magenta.y = 0; + pGdiInfo->ciDevice.Magenta.Y = 0; + pGdiInfo->ciDevice.Yellow.x = 0; + pGdiInfo->ciDevice.Yellow.y = 0; + pGdiInfo->ciDevice.Yellow.Y = 0; + pGdiInfo->ciDevice.MagentaInCyanDye = 0; + pGdiInfo->ciDevice.YellowInCyanDye = 0; + pGdiInfo->ciDevice.CyanInMagentaDye = 0; + pGdiInfo->ciDevice.YellowInMagentaDye = 0; + pGdiInfo->ciDevice.CyanInYellowDye = 0; + pGdiInfo->ciDevice.MagentaInYellowDye = 0; + pGdiInfo->ulDevicePelsDPI = 0; + pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA; + pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M; + pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS; + + pDevInfo->flGraphicsCaps = 0; + pDevInfo->lfDefaultFont = SystemFont; + pDevInfo->lfAnsiVarFont = AnsiVariableFont; + pDevInfo->lfAnsiFixFont = AnsiFixedFont; + pDevInfo->cFonts = 0; + pDevInfo->cxDither = 0; + pDevInfo->cyDither = 0; + pDevInfo->hpalDefault = 0; + pDevInfo->flGraphicsCaps2 = 0; + + if (ppdev->BitsPerPixel == 8) + { + pGdiInfo->ulNumColors = 20; + pGdiInfo->ulNumPalReg = 1 << ppdev->BitsPerPixel; + pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP; + pDevInfo->flGraphicsCaps |= GCAPS_PALMANAGED; + pDevInfo->iDitherFormat = BMF_8BPP; + /* Assuming palette is orthogonal - all colors are same size. */ + ppdev->PaletteShift = 8 - pGdiInfo->ulDACRed; + } + else + { + pGdiInfo->ulNumColors = (ULONG)(-1); + pGdiInfo->ulNumPalReg = 0; + switch (ppdev->BitsPerPixel) + { + case 16: + pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP; + pDevInfo->iDitherFormat = BMF_16BPP; + break; + + case 24: + pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP; + pDevInfo->iDitherFormat = BMF_24BPP; + break; + + default: + pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP; + pDevInfo->iDitherFormat = BMF_32BPP; + } + } + + EngFreeMem(ModeInfo); + return TRUE; +} + +/* + * DrvGetModes + * + * Returns the list of available modes for the device. + * + * Status + * @implemented + */ + +ULONG DDKAPI +DrvGetModes( + IN HANDLE hDriver, + IN ULONG cjSize, + OUT DEVMODEW *pdm) +{ + ULONG ModeCount; + ULONG ModeInfoSize; + PVIDEO_MODE_INFORMATION ModeInfo, ModeInfoPtr; + ULONG OutputSize; + + ModeCount = GetAvailableModes(hDriver, &ModeInfo, &ModeInfoSize); + if (ModeCount == 0) + { + return 0; + } + + if (pdm == NULL) + { + EngFreeMem(ModeInfo); + return ModeCount * sizeof(DEVMODEW); + } + + /* + * Copy the information about supported modes into the output buffer. + */ + + OutputSize = 0; + ModeInfoPtr = ModeInfo; + + while (ModeCount-- > 0) + { + if (ModeInfoPtr->Length == 0) + { + continue; + } + + memset(pdm, 0, sizeof(DEVMODEW)); + memcpy(pdm->dmDeviceName, DEVICE_NAME, sizeof(DEVICE_NAME)); + pdm->dmSpecVersion = + pdm->dmDriverVersion = DM_SPECVERSION; + pdm->dmSize = sizeof(DEVMODEW); + pdm->dmDriverExtra = 0; + pdm->dmBitsPerPel = ModeInfoPtr->NumberOfPlanes * ModeInfoPtr->BitsPerPlane; + pdm->dmPelsWidth = ModeInfoPtr->VisScreenWidth; + pdm->dmPelsHeight = ModeInfoPtr->VisScreenHeight; + pdm->dmDisplayFrequency = ModeInfoPtr->Frequency; + pdm->dmDisplayFlags = 0; + pdm->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | + DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS; + + ModeInfoPtr = (PVIDEO_MODE_INFORMATION)(((ULONG_PTR)ModeInfoPtr) + ModeInfoSize); + pdm = (LPDEVMODEW)(((ULONG_PTR)pdm) + sizeof(DEVMODEW)); + OutputSize += sizeof(DEVMODEW); + } + + EngFreeMem(ModeInfo); + return OutputSize; +} diff --git a/reactos/drivers/video/displays/framebuf/surface.c b/reactos/drivers/video/displays/framebuf/surface.c new file mode 100644 index 00000000000..8d02d5860a1 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf/surface.c @@ -0,0 +1,183 @@ +/* + * ReactOS Generic Framebuffer display driver + * + * Copyright (C) 2004 Filip Navara + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "framebuf.h" + +/* + * DrvEnableSurface + * + * Create engine bitmap around frame buffer and set the video mode requested + * when PDEV was initialized. + * + * Status + * @implemented + */ + +HSURF DDKAPI +DrvEnableSurface( + IN DHPDEV dhpdev) +{ + PPDEV ppdev = (PPDEV)dhpdev; + HSURF hSurface; + ULONG BitmapType; + SIZEL ScreenSize; + VIDEO_MEMORY VideoMemory; + VIDEO_MEMORY_INFORMATION VideoMemoryInfo; + ULONG ulTemp; + + /* + * Set video mode of our adapter. + */ + + if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_SET_CURRENT_MODE, + &(ppdev->ModeIndex), sizeof(ULONG), NULL, 0, + &ulTemp)) + { + return FALSE; + } + + /* + * Map the framebuffer into our memory. + */ + + VideoMemory.RequestedVirtualAddress = NULL; + if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_MAP_VIDEO_MEMORY, + &VideoMemory, sizeof(VIDEO_MEMORY), + &VideoMemoryInfo, sizeof(VIDEO_MEMORY_INFORMATION), + &ulTemp)) + { + return FALSE; + } + + ppdev->ScreenPtr = VideoMemoryInfo.FrameBufferBase; + + switch (ppdev->BitsPerPixel) + { + case 8: + IntSetPalette(dhpdev, ppdev->PaletteEntries, 0, 256); + BitmapType = BMF_8BPP; + break; + + case 16: + BitmapType = BMF_16BPP; + break; + + case 24: + BitmapType = BMF_24BPP; + break; + + case 32: + BitmapType = BMF_32BPP; + break; + } + + ScreenSize.cx = ppdev->ScreenWidth; + ScreenSize.cy = ppdev->ScreenHeight; + + hSurface = (HSURF)EngCreateBitmap(ScreenSize, ppdev->ScreenDelta, BitmapType, + (ppdev->ScreenDelta > 0) ? BMF_TOPDOWN : 0, + ppdev->ScreenPtr); + if (hSurface == NULL) + { + return FALSE; + } + + /* + * Associate the surface with our device. + */ + + if (!EngAssociateSurface(hSurface, ppdev->hDevEng, 0)) + { + EngDeleteSurface(hSurface); + return FALSE; + } + + ppdev->hSurfEng = hSurface; + + return hSurface; +} + +/* + * DrvDisableSurface + * + * Used by GDI to notify a driver that the surface created by DrvEnableSurface + * for the current device is no longer needed. + * + * Status + * @implemented + */ + +VOID DDKAPI +DrvDisableSurface( + IN DHPDEV dhpdev) +{ + DWORD ulTemp; + VIDEO_MEMORY VideoMemory; + + EngDeleteSurface(((PPDEV)dhpdev)->hSurfEng); + ((PPDEV)dhpdev)->hSurfEng = NULL; + + /* + * Unmap the framebuffer. + */ + + VideoMemory.RequestedVirtualAddress = ((PPDEV)dhpdev)->ScreenPtr; + EngDeviceIoControl(((PPDEV)dhpdev)->hDriver, IOCTL_VIDEO_UNMAP_VIDEO_MEMORY, + &VideoMemory, sizeof(VIDEO_MEMORY), NULL, 0, &ulTemp); +} + +/* + * DrvAssertMode + * + * Sets the mode of the specified physical device to either the mode specified + * when the PDEV was initialized or to the default mode of the hardware. + * + * Status + * @implemented + */ + +BOOL DDKAPI +DrvAssertMode( + IN DHPDEV dhpdev, + IN BOOL bEnable) +{ + PPDEV ppdev = (PPDEV)dhpdev; + ULONG ulTemp; + + if (bEnable) + { + /* + * Reinitialize the device to a clean state. + */ + + return !EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_SET_CURRENT_MODE, + &(ppdev->ModeIndex), sizeof(ULONG), NULL, 0, + &ulTemp); + } + else + { + /* + * Call the miniport driver to reset the device to a known state. + */ + + return !EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_RESET_DEVICE, + NULL, 0, NULL, 0, &ulTemp); + } +} diff --git a/reactos/drivers/video/makefile b/reactos/drivers/video/makefile index cccf9791936..21740bb671c 100644 --- a/reactos/drivers/video/makefile +++ b/reactos/drivers/video/makefile @@ -1,4 +1,4 @@ -DISPLAY_DRIVERS = vga +DISPLAY_DRIVERS = vga framebuf MINIPORT_DRIVERS = vga vbe all: $(DISPLAY_DRIVERS:%=DD%) $(MINIPORT_DRIVERS:%=MP%)