1 /*
2  * ReactOS Generic Framebuffer display driver directdraw interface
3  *
4  * Copyright (C) 2006 Magnus Olsen
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include "framebuf.h"
22 
23 VOID APIENTRY
24 DrvDisableDirectDraw( IN DHPDEV  dhpdev)
25 {
26    PPDEV ppdev = (PPDEV)dhpdev;
27    ppdev->bDDInitialized = FALSE;
28    /* Add Clean up code here if we need it
29       when we shout down directx interface */
30 }
31 
32 BOOL APIENTRY
33 DrvEnableDirectDraw(
34   IN DHPDEV  dhpdev,
35   OUT DD_CALLBACKS  *pCallBacks,
36   OUT DD_SURFACECALLBACKS  *pSurfaceCallBacks,
37   OUT DD_PALETTECALLBACKS  *pPaletteCallBacks)
38 {
39 	 PPDEV ppdev = (PPDEV)dhpdev;
40 
41 	 if (ppdev->bDDInitialized)
42 	 {
43 		 return TRUE;
44 	 }
45 
46 	 /* Setup pixel format */
47 	 ppdev->ddpfDisplay.dwSize = sizeof( DDPIXELFORMAT );
48      ppdev->ddpfDisplay.dwFourCC = 0;
49 
50      ppdev->ddpfDisplay.dwRBitMask = ppdev->RedMask;
51      ppdev->ddpfDisplay.dwGBitMask = ppdev->GreenMask;
52      ppdev->ddpfDisplay.dwBBitMask = ppdev->BlueMask;
53 
54      ppdev->ddpfDisplay.dwRGBBitCount=ppdev->BitsPerPixel;
55 	 ppdev->ddpfDisplay.dwRGBAlphaBitMask = 0;
56 	 ppdev->ddpfDisplay.dwFlags = DDPF_RGB;
57 
58 	 ppdev->pvmList = NULL;
59 
60 	 switch(ppdev->iDitherFormat)
61 	 {
62 		case BMF_8BPP:
63              ppdev->ddpfDisplay.dwFlags  |= DDPF_PALETTEINDEXED8;
64              break;
65 
66         case BMF_16BPP:
67              switch(ppdev->RedMask)
68              {
69                 case 0x7C00:
70                      ppdev->ddpfDisplay.dwRGBAlphaBitMask = 0x8000;
71                      break;
72 
73                 default:
74                      break;
75 			 }
76              break;
77 
78         case BMF_24BPP:
79              break;
80 
81         case BMF_32BPP:
82              ppdev->ddpfDisplay.dwRGBAlphaBitMask = 0xff000000;
83              break;
84 
85         default:
86            /* FIXME unknown pixel bits */
87 			ppdev->ddpfDisplay.dwRGBBitCount=0;
88             break;
89 	 }
90 
91 	 if (pCallBacks != NULL)
92 	 {
93 		 memset(pCallBacks,0,sizeof(DD_CALLBACKS));
94 
95 		 /* FILL pCallBacks with hal stuff */
96          pCallBacks->dwSize = sizeof(DDHAL_DDCALLBACKS);
97          pCallBacks->CanCreateSurface = (PDD_CANCREATESURFACE)DdCanCreateSurface;
98          pCallBacks->CreateSurface =  (PDD_CREATESURFACE)DdCreateSurface;
99 
100          /* Fill in the HAL Callback flags */
101          pCallBacks->dwFlags = DDHAL_CB32_CANCREATESURFACE | DDHAL_CB32_CREATESURFACE;
102 	 }
103 
104 	 if (pSurfaceCallBacks != NULL)
105 	 {
106 		 memset(pSurfaceCallBacks,0,sizeof(DD_SURFACECALLBACKS));
107 
108 		 /* FILL pSurfaceCallBacks with hal stuff */
109          // pSurfaceCallBacks.dwSize = sizeof(DDHAL_DDSURFACECALLBACKS);
110          // pSurfaceCallBacks.DestroySurface = DdDestroySurface;
111          // pSurfaceCallBacks.Lock = DdLock;
112          // pSurfaceCallBacks.Blt = DdBlt;
113 
114         // pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_DESTROYSURFACE | DDHAL_SURFCB32_LOCK | DDHAL_SURFCB32_BLT ;
115 	 }
116 
117 	 if (pPaletteCallBacks != NULL)
118 	 {
119 		 memset(pPaletteCallBacks,0,sizeof(DD_PALETTECALLBACKS));
120 		 /* FILL pPaletteCallBacks with hal stuff */
121 		 /* We will not support this callback in the framebuf.dll */
122 	 }
123 
124 
125 	 /* Fixme fill the ppdev->dxHalInfo with the info we need */
126 	 ppdev->bDDInitialized = TRUE;
127 	 return ppdev->bDDInitialized;
128 }
129 
130 BOOL APIENTRY
131 DrvGetDirectDrawInfo(
132   IN DHPDEV  dhpdev,
133   OUT DD_HALINFO  *pHalInfo,
134   OUT DWORD  *pdwNumHeaps,
135   OUT VIDEOMEMORY  *pvmList,
136   OUT DWORD  *pdwNumFourCCCodes,
137   OUT DWORD  *pdwFourCC)
138 {
139 	PPDEV ppdev = (PPDEV)dhpdev;
140 	LONG i;
141 	DWORD heap = 1; /* we always alloc one heap */
142 	BOOL bDDrawHeap = FALSE;
143 
144 	if  (ppdev == NULL)
145         return FALSE;
146 
147 	/*   check so pHalInfo,  pdwNumHeaps, pdwNumFourCCCodes is not NULL
148 	     pdwFourCC and pvmList can be null
149 	 */
150 
151 	if (pHalInfo == NULL)
152 		return FALSE;
153 
154 	if (pdwNumHeaps == NULL)
155 		return FALSE;
156 
157 	if (pdwNumFourCCCodes == NULL)
158 		return FALSE;
159 
160 	/*  Setup heap */
161 	if ( (ppdev->ScreenWidth < ppdev->MemWidth) || (ppdev->ScreenHeight < ppdev->MemHeight))
162     {
163        bDDrawHeap = TRUE;
164        heap++;
165     }
166 
167     ppdev->dwHeap = heap;
168     *pdwNumHeaps  = heap;
169 
170 	/* We do not support other fourcc */
171     *pdwNumFourCCCodes = 0;
172 
173 
174 	/*
175 	   check see if pvmList and pdwFourCC are frist call
176 	   or frist. Secon call  we fill in pHalInfo info
177     */
178 
179 	if(!(pvmList && pdwFourCC))
180 	{
181 
182          RtlZeroMemory(pHalInfo, sizeof(DD_HALINFO));
183          pHalInfo->dwSize = sizeof(DD_HALINFO);
184 
185 		 pHalInfo->ddCaps.dwCaps =  DDCAPS_BLT        | DDCAPS_BLTQUEUE | DDCAPS_BLTCOLORFILL | DDCAPS_READSCANLINE |
186 			                        DDCAPS_BLTSTRETCH | DDCAPS_COLORKEY | DDCAPS_CANBLTSYSMEM;
187 
188 		 pHalInfo->ddCaps.dwFXCaps = DDFXCAPS_BLTSTRETCHY     | DDFXCAPS_BLTSTRETCHX        |
189 			                         DDFXCAPS_BLTSTRETCHYN    | DDFXCAPS_BLTSTRETCHXN       |
190 									 DDFXCAPS_BLTSHRINKY      | DDFXCAPS_BLTSHRINKX         |
191                                      DDFXCAPS_BLTSHRINKYN     | DDFXCAPS_BLTSHRINKXN        |
192 									 DDFXCAPS_BLTMIRRORUPDOWN | DDFXCAPS_BLTMIRRORLEFTRIGHT;
193 
194 		pHalInfo->ddCaps.dwCaps2 = DDCAPS2_NONLOCALVIDMEM | DDCAPS2_NONLOCALVIDMEMCAPS;
195 
196 		pHalInfo->ddCaps.ddsCaps.dwCaps =  DDSCAPS_OFFSCREENPLAIN | DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP;
197 
198 		pHalInfo->ddCaps.dwCKeyCaps = DDCKEYCAPS_SRCBLT | DDCKEYCAPS_SRCBLTCLRSPACE;
199 
200 	    pHalInfo->ddCaps.dwSVBCaps = DDCAPS_BLT;
201 	    pHalInfo->ddCaps.ddsCaps.dwCaps |= DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM;
202 
203 		/* Calc how much memmory is left on the video cards memmory */
204 		pHalInfo->ddCaps.dwVidMemTotal = (ppdev->MemHeight - ppdev->ScreenHeight) * ppdev->ScreenDelta;
205 
206         /* fill in some basic info that we need */
207         pHalInfo->vmiData.pvPrimary                 = ppdev->ScreenPtr;
208         pHalInfo->vmiData.dwDisplayWidth            = ppdev->ScreenWidth;
209         pHalInfo->vmiData.dwDisplayHeight           = ppdev->ScreenHeight;
210         pHalInfo->vmiData.lDisplayPitch             = ppdev->ScreenDelta;
211         pHalInfo->vmiData.ddpfDisplay.dwSize        = sizeof(DDPIXELFORMAT);
212         pHalInfo->vmiData.ddpfDisplay.dwFlags       = DDPF_RGB;
213         pHalInfo->vmiData.ddpfDisplay.dwRGBBitCount = ppdev->BitsPerPixel;
214 		pHalInfo->vmiData.ddpfDisplay.dwRBitMask    = ppdev->RedMask;
215         pHalInfo->vmiData.ddpfDisplay.dwGBitMask    = ppdev->GreenMask;
216         pHalInfo->vmiData.ddpfDisplay.dwBBitMask    = ppdev->BlueMask;
217         pHalInfo->vmiData.dwOffscreenAlign = 4;
218 
219 		if ( ppdev->BitsPerPixel == 8 )
220 		{
221             pHalInfo->vmiData.ddpfDisplay.dwFlags |= DDPF_PALETTEINDEXED8;
222         }
223 
224 	    /*  FIXME
225 		    Config the rops we do not doing that yet
226 		     for we need write the rops table
227         */
228         for(i=0;i<DD_ROP_SPACE;i++ )
229         {
230            // pHALInfo->ddCaps.dwSVBRops[i] = rops[i];
231 		  //  pHALInfo->ddCaps.dwRops[i] = rops[i];
232         }
233 	}
234 
235 	/* Now build pvmList info */
236 	if(pvmList)
237 	{
238 		ppdev->pvmList = pvmList;
239 
240 		if (bDDrawHeap)
241 		{
242 			pvmList->dwFlags        = VIDMEM_ISLINEAR ;
243             pvmList->fpStart        = ppdev->ScreenHeight * ppdev->ScreenDelta;
244             pvmList->fpEnd          = ppdev->MemHeight * ppdev->ScreenDelta - 1;
245 			pvmList->ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
246 			pvmList++;
247 		}
248 
249 		pvmList->fpStart = 0;
250 		pvmList->fpEnd = (ppdev->MemHeight * ppdev->ScreenDelta)  - 1;
251 		pvmList->dwFlags = VIDMEM_ISNONLOCAL | VIDMEM_ISLINEAR | VIDMEM_ISWC;
252 		pvmList->ddsCaps.dwCaps =  DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER ;
253 		pvmList->ddsCapsAlt.dwCaps = DDSCAPS_FRONTBUFFER | DDSCAPS_BACKBUFFER;
254 
255 		pvmList = ppdev->pvmList;
256 	}
257 
258 	return TRUE;
259 }
260