From 793d6f38e6b06df84fb95961ee920aeedffbc5ab Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Wed, 31 Oct 2007 14:35:38 +0000 Subject: [PATCH] copy frambuf to framebuf_acc it will use system memory as cache, it will reduce the reading access of video memory, for reading video memory directly is slow and cost allot speed. svn path=/trunk/; revision=30013 --- .../drivers/video/displays/framebuf_acc/dd.c | 116 +++++ .../video/displays/framebuf_acc/ddenable.c | 260 +++++++++++ .../video/displays/framebuf_acc/enable.c | 164 +++++++ .../video/displays/framebuf_acc/framebuf.def | 3 + .../video/displays/framebuf_acc/framebuf.h | 166 +++++++ .../displays/framebuf_acc/framebuf.rbuild | 14 + .../video/displays/framebuf_acc/framebuf.rc | 5 + .../video/displays/framebuf_acc/palette.c | 192 ++++++++ .../video/displays/framebuf_acc/pointer.c | 370 ++++++++++++++++ .../video/displays/framebuf_acc/screen.c | 414 ++++++++++++++++++ .../video/displays/framebuf_acc/surface.c | 201 +++++++++ 11 files changed, 1905 insertions(+) create mode 100644 reactos/drivers/video/displays/framebuf_acc/dd.c create mode 100644 reactos/drivers/video/displays/framebuf_acc/ddenable.c create mode 100644 reactos/drivers/video/displays/framebuf_acc/enable.c create mode 100644 reactos/drivers/video/displays/framebuf_acc/framebuf.def create mode 100644 reactos/drivers/video/displays/framebuf_acc/framebuf.h create mode 100644 reactos/drivers/video/displays/framebuf_acc/framebuf.rbuild create mode 100644 reactos/drivers/video/displays/framebuf_acc/framebuf.rc create mode 100644 reactos/drivers/video/displays/framebuf_acc/palette.c create mode 100644 reactos/drivers/video/displays/framebuf_acc/pointer.c create mode 100644 reactos/drivers/video/displays/framebuf_acc/screen.c create mode 100644 reactos/drivers/video/displays/framebuf_acc/surface.c diff --git a/reactos/drivers/video/displays/framebuf_acc/dd.c b/reactos/drivers/video/displays/framebuf_acc/dd.c new file mode 100644 index 00000000000..3d29218989f --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/dd.c @@ -0,0 +1,116 @@ +/* + * ReactOS Generic Framebuffer display driver directdraw interface + * + * Copyright (C) 2006 Magnus Olsen + * + * 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. + */ + +/* Here we put in all 2d api for directdraw and redirect some of them to GDI api */ + +#include "framebuf.h" + + +DWORD CALLBACK +DdCanCreateSurface(LPDDHAL_CANCREATESURFACEDATA pccsd) +{ + + /* We do not support 3d buffer so we fail here */ + if ((pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) && + (pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY)) + { + pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT; + return DDHAL_DRIVER_HANDLED; + } + + + /* Check if another pixel format or not, we fail for now */ + if (pccsd->bIsDifferentPixelFormat) + { + /* check the fourcc diffent FOURCC, but we only support BMP for now */ + //if(pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC) + //{ + // /* We do not support other pixel format */ + // switch (pccsd->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC) + // { + // default: + // pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT; + // return DDHAL_DRIVER_HANDLED; + // } + //} + // /* check the texture support, we do not support testure for now */ + //else if((pccsd->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE)) + //{ + // /* We do not support texture surface */ + // pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT; + // return DDHAL_DRIVER_HANDLED; + //} + + /* Fail */ + pccsd->ddRVal = DDERR_INVALIDPIXELFORMAT; + return DDHAL_DRIVER_HANDLED; + } + + pccsd->ddRVal = DD_OK; + return DDHAL_DRIVER_HANDLED; +} + +DWORD CALLBACK +DdCreateSurface(PDD_CREATESURFACEDATA pcsd) +{ + int i; + + if (pcsd->dwSCnt < 1) + { + pcsd->ddRVal = DDERR_GENERIC; + return DDHAL_DRIVER_NOTHANDLED; + } + + + for (i=0; i<(int)pcsd->dwSCnt; i++) + { + pcsd->lplpSList[i]->lpGbl->lPitch = (DWORD)(pcsd->lplpSList[i]->lpGbl->wWidth * + (pcsd->lplpSList[i]->lpGbl->ddpfSurface.dwRGBBitCount / 8)); + + pcsd->lplpSList[i]->lpGbl->dwBlockSizeX = pcsd->lplpSList[i]->lpGbl->lPitch * + (DWORD)(pcsd->lplpSList[i]->lpGbl->wHeight); + + pcsd->lplpSList[i]->lpGbl->dwBlockSizeY = 1; + + if ( pcsd->lplpSList[i] ->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) + { + /* We maybe should alloc it with EngAlloc + for now we trusting ddraw alloc it */ + pcsd->lplpSList[i]->lpGbl->fpVidMem = 0; + } + else + { + + /* We maybe should alloc it with EngAlloc + for now we trusting ddraw alloc it */ + pcsd->lplpSList[i]->lpGbl->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE; + } + + pcsd->lpDDSurfaceDesc->lPitch = pcsd->lplpSList[i]->lpGbl->lPitch; + pcsd->lpDDSurfaceDesc->dwFlags |= DDSD_PITCH; + + } // for i + + + + pcsd->ddRVal = DD_OK; + return DDHAL_DRIVER_HANDLED; +} + diff --git a/reactos/drivers/video/displays/framebuf_acc/ddenable.c b/reactos/drivers/video/displays/framebuf_acc/ddenable.c new file mode 100644 index 00000000000..b88c27b0c29 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/ddenable.c @@ -0,0 +1,260 @@ +/* + * ReactOS Generic Framebuffer display driver directdraw interface + * + * Copyright (C) 2006 Magnus Olsen + * + * 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" + +VOID DDKAPI +DrvDisableDirectDraw( IN DHPDEV dhpdev) +{ + PPDEV ppdev = (PPDEV)dhpdev; + ppdev->bDDInitialized = FALSE; + /* Add Clean up code here if we need it + when we shout down directx interface */ +} + +BOOL DDKAPI +DrvEnableDirectDraw( + IN DHPDEV dhpdev, + OUT DD_CALLBACKS *pCallBacks, + OUT DD_SURFACECALLBACKS *pSurfaceCallBacks, + OUT DD_PALETTECALLBACKS *pPaletteCallBacks) +{ + PPDEV ppdev = (PPDEV)dhpdev; + + if (ppdev->bDDInitialized == TRUE) + { + return TRUE; + } + + /* Setup pixel format */ + ppdev->ddpfDisplay.dwSize = sizeof( DDPIXELFORMAT ); + ppdev->ddpfDisplay.dwFourCC = 0; + + ppdev->ddpfDisplay.dwRBitMask = ppdev->RedMask; + ppdev->ddpfDisplay.dwGBitMask = ppdev->GreenMask; + ppdev->ddpfDisplay.dwBBitMask = ppdev->BlueMask; + + ppdev->ddpfDisplay.dwRGBBitCount=ppdev->BitsPerPixel; + ppdev->ddpfDisplay.dwRGBAlphaBitMask = 0; + ppdev->ddpfDisplay.dwFlags = DDPF_RGB; + + ppdev->pvmList = NULL; + + switch(ppdev->iDitherFormat) + { + case BMF_8BPP: + ppdev->ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8; + break; + + case BMF_16BPP: + switch(ppdev->RedMask) + { + case 0x7C00: + ppdev->ddpfDisplay.dwRGBAlphaBitMask = 0x8000; + break; + + default: + break; + } + break; + + case BMF_24BPP: + break; + + case BMF_32BPP: + ppdev->ddpfDisplay.dwRGBAlphaBitMask = 0xff000000; + break; + + default: + /* FIXME unknown pixel bits */ + ppdev->ddpfDisplay.dwRGBBitCount=0; + break; + } + + if (pCallBacks !=NULL) + { + memset(pCallBacks,0,sizeof(DD_CALLBACKS)); + + /* FILL pCallBacks with hal stuff */ + pCallBacks->dwSize = sizeof(DDHAL_DDCALLBACKS); + pCallBacks->CanCreateSurface = (PDD_CANCREATESURFACE)DdCanCreateSurface; + pCallBacks->CreateSurface = (PDD_CREATESURFACE)DdCreateSurface; + + /* Fill in the HAL Callback flags */ + pCallBacks->dwFlags = DDHAL_CB32_CANCREATESURFACE | DDHAL_CB32_CREATESURFACE; + } + + if (pSurfaceCallBacks !=NULL) + { + memset(pSurfaceCallBacks,0,sizeof(DD_SURFACECALLBACKS)); + + /* FILL pSurfaceCallBacks with hal stuff */ + // pSurfaceCallBacks.dwSize = sizeof(DDHAL_DDSURFACECALLBACKS); + // pSurfaceCallBacks.DestroySurface = DdDestroySurface; + // pSurfaceCallBacks.Lock = DdLock; + // pSurfaceCallBacks.Blt = DdBlt; + + // pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_DESTROYSURFACE | DDHAL_SURFCB32_LOCK | DDHAL_SURFCB32_BLT ; + } + + if (pPaletteCallBacks !=NULL) + { + memset(pPaletteCallBacks,0,sizeof(DD_PALETTECALLBACKS)); + /* FILL pPaletteCallBacks with hal stuff */ + /* We will not support this callback in the framebuf.dll */ + } + + + /* Fixme fill the ppdev->dxHalInfo with the info we need */ + ppdev->bDDInitialized = TRUE; + return ppdev->bDDInitialized; +} + +BOOL DDKAPI +DrvGetDirectDrawInfo( + IN DHPDEV dhpdev, + OUT DD_HALINFO *pHalInfo, + OUT DWORD *pdwNumHeaps, + OUT VIDEOMEMORY *pvmList, + OUT DWORD *pdwNumFourCCCodes, + OUT DWORD *pdwFourCC) +{ + PPDEV ppdev = (PPDEV)dhpdev; + LONG i; + DWORD heap = 1; /* we always alloc one heap */ + BOOL bDDrawHeap = FALSE; + + if (ppdev == NULL) + return FALSE; + + /* check so pHalInfo, pdwNumHeaps, pdwNumFourCCCodes is not NULL + pdwFourCC and pvmList can be null + */ + + if (pHalInfo == NULL) + return FALSE; + + if (pdwNumHeaps == NULL) + return FALSE; + + if (pdwNumFourCCCodes == NULL) + return FALSE; + + /* Setup heap */ + if ( (ppdev->ScreenWidth < ppdev->MemWidth) || (ppdev->ScreenHeight < ppdev->MemHeight)) + { + bDDrawHeap = TRUE; + heap++; + } + + ppdev->dwHeap = heap; + *pdwNumHeaps = heap; + + /* We do not support other fourcc */ + *pdwNumFourCCCodes = 0; + + + /* + check see if pvmList and pdwFourCC are frist call + or frist. Secon call we fill in pHalInfo info + */ + + if(!(pvmList && pdwFourCC)) + { + + RtlZeroMemory(pHalInfo, sizeof(DD_HALINFO)); + pHalInfo->dwSize = sizeof(DD_HALINFO); + + pHalInfo->ddCaps.dwCaps = DDCAPS_BLT | DDCAPS_BLTQUEUE | DDCAPS_BLTCOLORFILL | DDCAPS_READSCANLINE | + DDCAPS_BLTSTRETCH | DDCAPS_COLORKEY | DDCAPS_CANBLTSYSMEM; + + pHalInfo->ddCaps.dwFXCaps = DDFXCAPS_BLTSTRETCHY | DDFXCAPS_BLTSTRETCHX | + DDFXCAPS_BLTSTRETCHYN | DDFXCAPS_BLTSTRETCHXN | + DDFXCAPS_BLTSHRINKY | DDFXCAPS_BLTSHRINKX | + DDFXCAPS_BLTSHRINKYN | DDFXCAPS_BLTSHRINKXN | + DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTMIRRORLEFTRIGHT; + + pHalInfo->ddCaps.dwCaps2 = DDCAPS2_NONLOCALVIDMEM | DDCAPS2_NONLOCALVIDMEMCAPS; + + pHalInfo->ddCaps.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP; + + pHalInfo->ddCaps.dwCKeyCaps = DDCKEYCAPS_SRCBLT | DDCKEYCAPS_SRCBLTCLRSPACE; + + pHalInfo->ddCaps.dwSVBCaps = DDCAPS_BLT; + pHalInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM; + + /* Calc how much memmory is left on the video cards memmory */ + pHalInfo->ddCaps.dwVidMemTotal = (ppdev->MemHeight - ppdev->ScreenHeight) * ppdev->ScreenDelta; + + /* fill in some basic info that we need */ + pHalInfo->vmiData.pvPrimary = ppdev->ScreenPtr; + pHalInfo->vmiData.dwDisplayWidth = ppdev->ScreenWidth; + pHalInfo->vmiData.dwDisplayHeight = ppdev->ScreenHeight; + pHalInfo->vmiData.lDisplayPitch = ppdev->ScreenDelta; + pHalInfo->vmiData.ddpfDisplay.dwSize = sizeof(DDPIXELFORMAT); + pHalInfo->vmiData.ddpfDisplay.dwFlags = DDPF_RGB; + pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount = ppdev->BitsPerPixel; + pHalInfo->vmiData.ddpfDisplay.dwRBitMask = ppdev->RedMask; + pHalInfo->vmiData.ddpfDisplay.dwGBitMask = ppdev->GreenMask; + pHalInfo->vmiData.ddpfDisplay.dwBBitMask = ppdev->BlueMask; + pHalInfo->vmiData.dwOffscreenAlign = 4; + + if ( ppdev->BitsPerPixel == 8 ) + { + pHalInfo->vmiData.ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8; + } + + /* FIXME + Config the rops we do not doing that yet + for we need write the rops table + */ + for(i=0;iddCaps.dwSVBRops[i] = rops[i]; + // pHALInfo->ddCaps.dwRops[i] = rops[i]; + } + } + + /* Now build pvmList info */ + if(pvmList) + { + ppdev->pvmList = pvmList; + + if ( bDDrawHeap == TRUE) + { + pvmList->dwFlags = VIDMEM_ISLINEAR ; + pvmList->fpStart = ppdev->ScreenHeight * ppdev->ScreenDelta; + pvmList->fpEnd = ppdev->MemHeight * ppdev->ScreenDelta - 1; + pvmList->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; + pvmList++; + } + + pvmList->fpStart = 0; + pvmList->fpEnd = (ppdev->MemHeight * ppdev->ScreenDelta) - 1; + pvmList->dwFlags = VIDMEM_ISNONLOCAL | VIDMEM_ISLINEAR | VIDMEM_ISWC; + pvmList->ddsCaps.dwCaps = DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER ; + pvmList->ddsCapsAlt.dwCaps = DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER; + + pvmList = ppdev->pvmList; + } + + return TRUE; +} + diff --git a/reactos/drivers/video/displays/framebuf_acc/enable.c b/reactos/drivers/video/displays/framebuf_acc/enable.c new file mode 100644 index 00000000000..9ba41777bfa --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/enable.c @@ -0,0 +1,164 @@ +/* + * 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 APIENTRY +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 APIENTRY +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 APIENTRY +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 APIENTRY +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_acc/framebuf.def b/reactos/drivers/video/displays/framebuf_acc/framebuf.def new file mode 100644 index 00000000000..3ab97ffa6b8 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/framebuf.def @@ -0,0 +1,3 @@ +LIBRARY framebuf.dll +EXPORTS +DrvEnableDriver@12 diff --git a/reactos/drivers/video/displays/framebuf_acc/framebuf.h b/reactos/drivers/video/displays/framebuf_acc/framebuf.h new file mode 100644 index 00000000000..e66c756a6c2 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/framebuf.h @@ -0,0 +1,166 @@ +/* + * 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 +#include +#include +#include + +//#define EXPERIMENTAL_MOUSE_CURSOR_SUPPORT + +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; + +#ifdef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT + VIDEO_POINTER_ATTRIBUTES PointerAttributes; + XLATEOBJ *PointerXlateObject; + HSURF PointerColorSurface; + HSURF PointerMaskSurface; + HSURF PointerSaveSurface; + POINTL PointerHotSpot; +#endif + + /* DirectX Support */ + DWORD iDitherFormat; + ULONG MemHeight; + ULONG MemWidth; + DWORD dwHeap; + VIDEOMEMORY* pvmList; + BOOL bDDInitialized; + DDPIXELFORMAT ddpfDisplay; +} PDEV, *PPDEV; + +#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) + +#define DEVICE_NAME L"framebuf" +#define ALLOC_TAG TAG('F','B','U','F') + + +DHPDEV APIENTRY +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 APIENTRY +DrvCompletePDEV( + IN DHPDEV dhpdev, + IN HDEV hdev); + +VOID APIENTRY +DrvDisablePDEV( + IN DHPDEV dhpdev); + +HSURF APIENTRY +DrvEnableSurface( + IN DHPDEV dhpdev); + +VOID APIENTRY +DrvDisableSurface( + IN DHPDEV dhpdev); + +BOOL APIENTRY +DrvAssertMode( + IN DHPDEV dhpdev, + IN BOOL bEnable); + +ULONG APIENTRY +DrvGetModes( + IN HANDLE hDriver, + IN ULONG cjSize, + OUT DEVMODEW *pdm); + +BOOL APIENTRY +DrvSetPalette( + IN DHPDEV dhpdev, + IN PALOBJ *ppalo, + IN FLONG fl, + IN ULONG iStart, + IN ULONG cColors); + +ULONG APIENTRY +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 APIENTRY +DrvMovePointer( + IN SURFOBJ *pso, + IN LONG x, + IN LONG y, + IN RECTL *prcl); + +BOOL +IntInitScreenInfo( + PPDEV ppdev, + LPDEVMODEW pDevMode, + PGDIINFO pGdiInfo, + PDEVINFO pDevInfo); + +BOOL +IntInitDefaultPalette( + PPDEV ppdev, + PDEVINFO pDevInfo); + +BOOL APIENTRY +IntSetPalette( + IN DHPDEV dhpdev, + IN PPALETTEENTRY ppalent, + IN ULONG iStart, + IN ULONG cColors); + +#endif /* FRAMEBUF_H */ diff --git a/reactos/drivers/video/displays/framebuf_acc/framebuf.rbuild b/reactos/drivers/video/displays/framebuf_acc/framebuf.rbuild new file mode 100644 index 00000000000..1f5e2bd5e2d --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/framebuf.rbuild @@ -0,0 +1,14 @@ + + + + + . + win32k + libcntpr + enable.c + palette.c + pointer.c + screen.c + surface.c + framebuf.rc + diff --git a/reactos/drivers/video/displays/framebuf_acc/framebuf.rc b/reactos/drivers/video/displays/framebuf_acc/framebuf.rc new file mode 100644 index 00000000000..96adb55f862 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/framebuf.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "Framebuffer Display Driver\0" +#define REACTOS_STR_INTERNAL_NAME "framebuf\0" +#define REACTOS_STR_ORIGINAL_FILENAME "framebuf.dll\0" +#include diff --git a/reactos/drivers/video/displays/framebuf_acc/palette.c b/reactos/drivers/video/displays/framebuf_acc/palette.c new file mode 100644 index 00000000000..ef2cc048c78 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/palette.c @@ -0,0 +1,192 @@ +/* + * 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 }, + { 0xD4, 0xD0, 0xC8, 0x00 }, + { 0xFF, 0xFB, 0xF0, 0x00 }, + { 0x3A, 0x6E, 0xA5, 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 +IntInitDefaultPalette( + PPDEV ppdev, + PDEVINFO pDevInfo) +{ + ULONG ColorLoop; + PPALETTEENTRY PaletteEntryPtr; + + if (ppdev->BitsPerPixel > 8) + { + ppdev->DefaultPalette = pDevInfo->hpalDefault = + EngCreatePalette(PAL_BITFIELDS, 0, NULL, + ppdev->RedMask, ppdev->GreenMask, ppdev->BlueMask); + } + else + { + ppdev->PaletteEntries = EngAllocMem(0, sizeof(PALETTEENTRY) << 8, ALLOC_TAG); + if (ppdev->PaletteEntries == NULL) + { + return FALSE; + } + + for (ColorLoop = 256, PaletteEntryPtr = ppdev->PaletteEntries; + ColorLoop != 0; + ColorLoop--, PaletteEntryPtr++) + { + PaletteEntryPtr->peRed = ((ColorLoop >> 5) & 7) * 255 / 7; + PaletteEntryPtr->peGreen = ((ColorLoop >> 3) & 3) * 255 / 3; + PaletteEntryPtr->peBlue = (ColorLoop & 7) * 255 / 7; + PaletteEntryPtr->peFlags = 0; + } + + 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 APIENTRY +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 APIENTRY +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_acc/pointer.c b/reactos/drivers/video/displays/framebuf_acc/pointer.c new file mode 100644 index 00000000000..9b1b1136829 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/pointer.c @@ -0,0 +1,370 @@ +/* + * 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" + +#ifndef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT + +/* + * DrvSetPointerShape + * + * Sets the new pointer shape. + * + * Status + * @unimplemented + */ + +ULONG APIENTRY +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;*/ + return EngSetPointerShape(pso, psoMask, psoColor, pxlo, xHot, yHot, x, y, prcl, fl); +} + +/* + * DrvMovePointer + * + * Moves the pointer to a new position and ensures that GDI does not interfere + * with the display of the pointer. + * + * Status + * @unimplemented + */ + +VOID APIENTRY +DrvMovePointer( + IN SURFOBJ *pso, + IN LONG x, + IN LONG y, + IN RECTL *prcl) +{ + return EngMovePointer(pso, x, y, prcl); +} + +#else + +VOID FASTCALL +IntHideMousePointer(PPDEV ppdev, SURFOBJ *DestSurface) +{ + if (ppdev->PointerAttributes.Enable == FALSE) + { + return; + } + + ppdev->PointerAttributes.Enable = FALSE; + if (ppdev->PointerSaveSurface != NULL) + { + RECTL DestRect; + POINTL SrcPoint; + SURFOBJ *SaveSurface; + SURFOBJ *MaskSurface; + + DestRect.left = max(ppdev->PointerAttributes.Column, 0); + DestRect.top = max(ppdev->PointerAttributes.Row, 0); + DestRect.right = min( + ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width, + ppdev->ScreenWidth - 1); + DestRect.bottom = min( + ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height, + ppdev->ScreenHeight - 1); + + SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0); + SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0); + + SaveSurface = EngLockSurface(ppdev->PointerSaveSurface); + MaskSurface = EngLockSurface(ppdev->PointerMaskSurface); + EngBitBlt(DestSurface, SaveSurface, MaskSurface, NULL, NULL, + &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, SRCCOPY); + EngUnlockSurface(MaskSurface); + EngUnlockSurface(SaveSurface); + } +} + +VOID FASTCALL +IntShowMousePointer(PPDEV ppdev, SURFOBJ *DestSurface) +{ + if (ppdev->PointerAttributes.Enable == TRUE) + { + return; + } + + ppdev->PointerAttributes.Enable = TRUE; + + /* + * Copy the pixels under the cursor to temporary surface. + */ + + if (ppdev->PointerSaveSurface != NULL) + { + RECTL DestRect; + POINTL SrcPoint; + SURFOBJ *SaveSurface; + + SrcPoint.x = max(ppdev->PointerAttributes.Column, 0); + SrcPoint.y = max(ppdev->PointerAttributes.Row, 0); + + DestRect.left = SrcPoint.x - ppdev->PointerAttributes.Column; + DestRect.top = SrcPoint.y - ppdev->PointerAttributes.Row; + DestRect.right = min( + ppdev->PointerAttributes.Width, + ppdev->ScreenWidth - ppdev->PointerAttributes.Column - 1); + DestRect.bottom = min( + ppdev->PointerAttributes.Height, + ppdev->ScreenHeight - ppdev->PointerAttributes.Row - 1); + + SaveSurface = EngLockSurface(ppdev->PointerSaveSurface); + EngBitBlt(SaveSurface, DestSurface, NULL, NULL, NULL, + &DestRect, &SrcPoint, NULL, NULL, NULL, SRCCOPY); + EngUnlockSurface(SaveSurface); + } + + /* + * Blit the cursor on the screen. + */ + + { + RECTL DestRect; + POINTL SrcPoint; + SURFOBJ *ColorSurf; + SURFOBJ *MaskSurf; + + DestRect.left = max(ppdev->PointerAttributes.Column, 0); + DestRect.top = max(ppdev->PointerAttributes.Row, 0); + DestRect.right = min( + ppdev->PointerAttributes.Column + ppdev->PointerAttributes.Width, + ppdev->ScreenWidth - 1); + DestRect.bottom = min( + ppdev->PointerAttributes.Row + ppdev->PointerAttributes.Height, + ppdev->ScreenHeight - 1); + + SrcPoint.x = max(-ppdev->PointerAttributes.Column, 0); + SrcPoint.y = max(-ppdev->PointerAttributes.Row, 0); + + MaskSurf = EngLockSurface(ppdev->PointerMaskSurface); + if (ppdev->PointerColorSurface != NULL) + { + ColorSurf = EngLockSurface(ppdev->PointerColorSurface); + EngBitBlt(DestSurface, ColorSurf, MaskSurf, NULL, ppdev->PointerXlateObject, + &DestRect, &SrcPoint, &SrcPoint, NULL, NULL, 0xAACC); + EngUnlockSurface(ColorSurf); + } + else + { + /* FIXME */ + EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject, + &DestRect, &SrcPoint, NULL, NULL, NULL, SRCAND); + SrcPoint.y += ppdev->PointerAttributes.Height; + EngBitBlt(DestSurface, MaskSurf, NULL, NULL, ppdev->PointerXlateObject, + &DestRect, &SrcPoint, NULL, NULL, NULL, SRCINVERT); + } + EngUnlockSurface(MaskSurf); + } +} + +/* + * DrvSetPointerShape + * + * Sets the new pointer shape. + * + * Status + * @implemented + */ + +ULONG APIENTRY +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) +{ + PPDEV ppdev = (PPDEV)pso->dhpdev; + SURFOBJ *TempSurfObj; + + IntHideMousePointer(ppdev, pso); + + if (ppdev->PointerColorSurface != NULL) + { + /* FIXME: Is this really needed? */ + TempSurfObj = EngLockSurface(ppdev->PointerColorSurface); + EngFreeMem(TempSurfObj->pvBits); + TempSurfObj->pvBits = 0; + EngUnlockSurface(TempSurfObj); + + EngDeleteSurface(ppdev->PointerColorSurface); + ppdev->PointerMaskSurface = NULL; + } + + if (ppdev->PointerMaskSurface != NULL) + { + /* FIXME: Is this really needed? */ + TempSurfObj = EngLockSurface(ppdev->PointerMaskSurface); + EngFreeMem(TempSurfObj->pvBits); + TempSurfObj->pvBits = 0; + EngUnlockSurface(TempSurfObj); + + EngDeleteSurface(ppdev->PointerMaskSurface); + ppdev->PointerMaskSurface = NULL; + } + + if (ppdev->PointerSaveSurface != NULL) + { + EngDeleteSurface(ppdev->PointerSaveSurface); + ppdev->PointerSaveSurface = NULL; + } + + /* + * See if we are being asked to hide the pointer. + */ + + if (psoMask == NULL) + { + return SPS_ACCEPT_EXCLUDE; + } + + ppdev->PointerHotSpot.x = xHot; + ppdev->PointerHotSpot.y = yHot; + + ppdev->PointerXlateObject = pxlo; + ppdev->PointerAttributes.Column = x - xHot; + ppdev->PointerAttributes.Row = y - yHot; + ppdev->PointerAttributes.Width = psoMask->lDelta << 3; + ppdev->PointerAttributes.Height = (psoMask->cjBits / psoMask->lDelta) >> 1; + + if (psoColor != NULL) + { + SIZEL Size; + PBYTE Bits; + + Size.cx = ppdev->PointerAttributes.Width; + Size.cy = ppdev->PointerAttributes.Height; + Bits = EngAllocMem(0, psoColor->cjBits, ALLOC_TAG); + memcpy(Bits, psoColor->pvBits, psoColor->cjBits); + + ppdev->PointerColorSurface = (HSURF)EngCreateBitmap(Size, + psoColor->lDelta, psoColor->iBitmapFormat, 0, Bits); + } + else + { + ppdev->PointerColorSurface = NULL; + } + + if (psoMask != NULL) + { + SIZEL Size; + PBYTE Bits; + + Size.cx = ppdev->PointerAttributes.Width; + Size.cy = ppdev->PointerAttributes.Height << 1; + Bits = EngAllocMem(0, psoMask->cjBits, ALLOC_TAG); + memcpy(Bits, psoMask->pvBits, psoMask->cjBits); + + ppdev->PointerMaskSurface = (HSURF)EngCreateBitmap(Size, + psoMask->lDelta, psoMask->iBitmapFormat, 0, Bits); + } + else + { + ppdev->PointerMaskSurface = NULL; + } + + /* + * Create surface for saving the pixels under the cursor. + */ + + { + SIZEL Size; + LONG lDelta; + + Size.cx = ppdev->PointerAttributes.Width; + Size.cy = ppdev->PointerAttributes.Height; + + switch (pso->iBitmapFormat) + { + case BMF_8BPP: lDelta = Size.cx; break; + case BMF_16BPP: lDelta = Size.cx << 1; break; + case BMF_24BPP: lDelta = Size.cx * 3; break; + case BMF_32BPP: lDelta = Size.cx << 2; break; + } + + ppdev->PointerSaveSurface = (HSURF)EngCreateBitmap( + Size, lDelta, pso->iBitmapFormat, BMF_NOZEROINIT, NULL); + } + + IntShowMousePointer(ppdev, pso); + + return SPS_ACCEPT_EXCLUDE; +} + +/* + * DrvMovePointer + * + * Moves the pointer to a new position and ensures that GDI does not interfere + * with the display of the pointer. + * + * Status + * @implemented + */ + +VOID APIENTRY +DrvMovePointer( + IN SURFOBJ *pso, + IN LONG x, + IN LONG y, + IN RECTL *prcl) +{ + PPDEV ppdev = (PPDEV)pso->dhpdev; + BOOL WasVisible; + + WasVisible = ppdev->PointerAttributes.Enable; + if (WasVisible) + { + IntHideMousePointer(ppdev, pso); + } + + if (x == -1) + { + return; + } + + ppdev->PointerAttributes.Column = x - ppdev->PointerHotSpot.x; + ppdev->PointerAttributes.Row = y - ppdev->PointerHotSpot.y; + + if (WasVisible) + { + IntShowMousePointer(ppdev, pso); + } +} + +#endif diff --git a/reactos/drivers/video/displays/framebuf_acc/screen.c b/reactos/drivers/video/displays/framebuf_acc/screen.c new file mode 100644 index 00000000000..6ce68449228 --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/screen.c @@ -0,0 +1,414 @@ +/* + * 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 +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 +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) + { + ModeInfoPtr = (PVIDEO_MODE_INFORMATION) + (((PUCHAR)ModeInfoPtr) + ModeInfoSize); + continue; + } + SelectedMode = ModeInfoPtr; + break; + } + } + else + { + ModeInfoPtr = ModeInfo; + while (ModeCount-- > 0) + { + if (ModeInfoPtr->Length > 0 && + pDevMode->dmPelsWidth == ModeInfoPtr->VisScreenWidth && + pDevMode->dmPelsHeight == ModeInfoPtr->VisScreenHeight && + pDevMode->dmBitsPerPel == (ModeInfoPtr->BitsPerPlane * + ModeInfoPtr->NumberOfPlanes) && + pDevMode->dmDisplayFrequency == ModeInfoPtr->Frequency) + { + SelectedMode = ModeInfoPtr; + break; + } + + ModeInfoPtr = (PVIDEO_MODE_INFORMATION) + (((PUCHAR)ModeInfoPtr) + ModeInfoSize); + } + } + + 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->MemWidth = SelectedMode->VideoMemoryBitmapWidth; + ppdev->MemHeight = SelectedMode->VideoMemoryBitmapHeight; + + 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->flRaster = 0; + 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 APIENTRY +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) + { + ModeInfoPtr = (PVIDEO_MODE_INFORMATION)(((ULONG_PTR)ModeInfoPtr) + ModeInfoSize); + 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_acc/surface.c b/reactos/drivers/video/displays/framebuf_acc/surface.c new file mode 100644 index 00000000000..d4b024af6bb --- /dev/null +++ b/reactos/drivers/video/displays/framebuf_acc/surface.c @@ -0,0 +1,201 @@ +/* + * 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 APIENTRY +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; + + default: + return FALSE; + } + + ppdev->iDitherFormat = BitmapType; + + 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 APIENTRY +DrvDisableSurface( + IN DHPDEV dhpdev) +{ + DWORD ulTemp; + VIDEO_MEMORY VideoMemory; + PPDEV ppdev = (PPDEV)dhpdev; + + EngDeleteSurface(ppdev->hSurfEng); + ppdev->hSurfEng = NULL; + +#ifdef EXPERIMENTAL_MOUSE_CURSOR_SUPPORT + /* Clear all mouse pointer surfaces. */ + DrvSetPointerShape(NULL, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0); +#endif + + /* + * 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 APIENTRY +DrvAssertMode( + IN DHPDEV dhpdev, + IN BOOL bEnable) +{ + PPDEV ppdev = (PPDEV)dhpdev; + ULONG ulTemp; + + if (bEnable) + { + BOOLEAN Result; + /* + * Reinitialize the device to a clean state. + */ + Result = EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_SET_CURRENT_MODE, + &(ppdev->ModeIndex), sizeof(ULONG), NULL, 0, + &ulTemp); + if (ppdev->BitsPerPixel == 8) + { + IntSetPalette(dhpdev, ppdev->PaletteEntries, 0, 256); + } + + return Result; + + } + 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); + } +}