branch update for HEAD-2003050101
[reactos.git] / drivers / dd / vga / display / main / enable.c
1 /*
2  * entry.c
3  *
4  * $Revision$
5  * $Author$
6  * $Date$
7  *
8  */
9
10 #include "gdiinfo.h"
11 #include "../vgavideo/vgavideo.h"
12 #define NDEBUG
13 #include <debug.h>
14
15 #define  DBG_PREFIX  "VGADDI: "
16
17 static BOOL VGAInitialized = FALSE;
18
19 DRVFN FuncList[] =
20 {
21   /*  Required Display driver fuctions  */
22   {INDEX_DrvAssertMode, (PFN) DrvAssertMode},
23   {INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV},
24   {INDEX_DrvCopyBits, (PFN) DrvCopyBits},
25   {INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV},
26   {INDEX_DrvDisableSurface, (PFN) DrvDisableSurface},
27   {INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV},
28   {INDEX_DrvEnableSurface, (PFN) DrvEnableSurface},
29   {INDEX_DrvGetModes, (PFN) DrvGetModes},
30   {INDEX_DrvLineTo, (PFN) DrvLineTo},
31   {INDEX_DrvPaint, (PFN) DrvPaint},
32   {INDEX_DrvBitBlt, (PFN) DrvBitBlt},
33   {INDEX_DrvTransparentBlt, (PFN) DrvTransparentBlt},
34   {INDEX_DrvMovePointer, (PFN) DrvMovePointer},
35   {INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape},
36
37 #if 0
38   /*  Optional Display driver functions  */
39   {INDEX_, (PFN) },
40   {INDEX_DescribePixelFormat, (PFN) VGADDIDescribePixelFormat},
41   {INDEX_DrvDitherColor, (PFN) VGADDIDitherColor},
42   {INDEX_DrvFillPath, (PFN) VGADDIFillPath},
43   {INDEX_DrvGetTrueTypeFile, (PFN) VGADDIGetTrueTypeFile},
44   {INDEX_DrvLoadFontFile, (PFN) VGADDILoadFontFile},
45   {INDEX_DrvQueryFont, (PFN) VGADDIQueryFont},
46   {INDEX_DrvQueryFontCaps, (PFN) VGADDIQueryFontCaps},
47   {INDEX_DrvQueryFontData, (PFN) VGADDIQueryFontData},
48   {INDEX_DrvQueryFontFile, (PFN) VGADDIQueryFontFile},
49   {INDEX_DrvQueryFontTree, (PFN) VGADDIQueryFontTree},
50   {INDEX_DrvQueryTrueTypeOutline, (PFN) VGADDIQueryTrueTypeOutline},
51   {INDEX_DrvQueryTrueTypeTable, (PFN) VGADDIQueryTrueTypeTable},
52   {INDEX_DrvRealizeBrush, (PFN) VGADDIRealizeBrush},
53   {INDEX_DrvResetPDEV, (PFN) VGADDIResetPDEV},
54   {INDEX_DrvSetPalette, (PFN) VGADDISetPalette},
55   {INDEX_DrvSetPixelFormat, (PFN) VGADDISetPixelFormat},
56   {INDEX_DrvStretchBlt, (PFN) VGADDIStretchBlt},
57   {INDEX_DrvStrokePath, (PFN) VGADDIStrokePath},
58   {INDEX_DrvSwapBuffers, (PFN) VGADDISwapBuffers},
59   {INDEX_DrvTextOut, (PFN) VGADDITextOut},
60   {INDEX_DrvUnloadFontFile, (PFN) VGADDIUnloadFontFile},
61 #endif
62 };
63
64
65 BOOL STDCALL
66 DrvEnableDriver(IN ULONG EngineVersion,
67                 IN ULONG SizeOfDED,
68                 OUT PDRVENABLEDATA DriveEnableData)
69 {
70   EngDebugPrint("VGADDI", "DrvEnableDriver called...\n", 0);
71
72   vgaPreCalc();
73
74   // FIXME: Use Vidport to map the memory properly
75   vidmem = (char *)(0xd0000000 + 0xa0000);
76
77   VGADDI_InitializeOffScreenMem((640 * 480) >> 3, 65536 - ((640 * 480) >> 3));
78
79   DriveEnableData->pdrvfn = FuncList;
80   DriveEnableData->c = sizeof(FuncList) / sizeof(DRVFN);
81   DriveEnableData->iDriverVersion = DDI_DRIVER_VERSION;
82
83   return  TRUE;
84 }
85
86 //    DrvDisableDriver
87 //  DESCRIPTION:
88 //    This function is called by the KMGDI at exit.  It should cleanup.
89 //  ARGUMENTS:
90 //    NONE
91 //  RETURNS:
92 //    NONE
93
94 VOID STDCALL
95 DrvDisableDriver(VOID)
96 {
97   return;
98 }
99
100 //  -----------------------------------------------  Driver Implementation 
101
102
103 //    DrvEnablePDEV
104 //  DESCRIPTION:
105 //    This function is called after DrvEnableDriver to get information
106 //    about the mode that is to be used.  This function just returns
107 //    information, and should not yet initialize the mode.
108 //  ARGUMENTS:
109 //    IN DEVMODEW *  DM            Describes the mode requested
110 //    IN LPWSTR      LogAddress    
111 //    IN ULONG       PatternCount  number of patterns expected
112 //    OUT HSURF *    SurfPatterns  array to contain pattern handles
113 //    IN ULONG       CapsSize      the size of the DevCaps object passed in
114 //    OUT ULONG *    DevCaps       Device Capabilities object
115 //    IN ULONG       DevInfoSize   the size of the DevInfo object passed in
116 //    OUT DEVINFO *  DI            Device Info object
117 //    IN LPWSTR      DevDataFile   ignore
118 //    IN LPWSTR      DeviceName    Device name
119 //    IN HANDLE      Driver        handle to KM driver
120 //  RETURNS:
121 //    DHPDEV  a handle to a DPev object
122
123 DHPDEV STDCALL
124 DrvEnablePDEV(IN DEVMODEW *DM,
125               IN LPWSTR LogAddress,
126               IN ULONG PatternCount,
127               OUT HSURF *SurfPatterns,
128               IN ULONG CapsSize,
129               OUT ULONG *DevCaps,
130               IN ULONG DevInfoSize,
131               OUT DEVINFO *DI,
132               IN LPWSTR DevDataFile,
133               IN LPWSTR DeviceName,
134               IN HANDLE Driver)
135 {
136   PPDEV  PDev;
137
138   PDev = EngAllocMem(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG);
139   if (PDev == NULL)
140     {
141       EngDebugPrint(DBG_PREFIX, "EngAllocMem failed for PDEV\n", 0);
142       return(NULL);
143     }
144   PDev->KMDriver = Driver;
145   DPRINT( "PDev: %x, Driver: %x\n", PDev, PDev->KMDriver );
146   PDev->xyCursor.x = 320;
147   PDev->xyCursor.y = 240;
148   PDev->ptlExtent.x = 0;
149   PDev->ptlExtent.y = 0;
150   PDev->cExtent = 0;
151   PDev->flCursor = CURSOR_DOWN;
152   // FIXME: fill out DevCaps
153   // FIXME: full out DevInfo
154
155   devinfoVGA.hpalDefault = EngCreatePalette(PAL_INDEXED, 16, (PULONG *)VGApalette.PaletteEntry, 0, 0, 0);
156 DPRINT("Palette from Driver: %u\n", devinfoVGA.hpalDefault);
157   *DI = devinfoVGA;
158 DPRINT("Palette from Driver 2: %u and DI is %08x\n", DI->hpalDefault, DI);
159
160   return(PDev);
161 }
162
163
164 //    DrvCompletePDEV
165 //  DESCRIPTION
166 //    Called after initialization of PDEV is complete.  Supplies
167 //    a reference to the GDI handle for the PDEV.
168
169 VOID STDCALL
170 DrvCompletePDEV(IN DHPDEV PDev,
171                 IN HDEV Dev)
172 {
173   ((PPDEV) PDev)->GDIDevHandle = Dev; // Handle to the DC
174 }
175
176
177 BOOL STDCALL
178 DrvAssertMode(IN DHPDEV DPev,
179               IN BOOL Enable)
180 {
181   PPDEV ppdev = (PPDEV)DPev;
182   ULONG returnedDataLength;
183
184   if(Enable==TRUE)
185   {
186     // Reenable our graphics mode
187
188     if (!InitPointer(ppdev))
189     {
190       // Failed to set pointer
191       return FALSE;
192     }
193
194     if (!VGAInitialized)
195       {
196         if (!InitVGA(ppdev, FALSE))
197           {
198             // Failed to initialize the VGA
199             return FALSE;
200           }
201         VGAInitialized = TRUE;
202       }
203   } else {
204     // Go back to last known mode
205     DPRINT( "ppdev: %x, KMDriver: %x", ppdev, ppdev->KMDriver );
206     if (EngDeviceIoControl(ppdev->KMDriver, IOCTL_VIDEO_RESET_DEVICE, NULL, 0, NULL, 0, &returnedDataLength))
207     {
208       // Failed to go back to mode
209       return FALSE;
210     }
211     VGAInitialized = FALSE;
212   }
213   return TRUE;
214 }
215
216
217 VOID STDCALL
218 DrvDisablePDEV(IN DHPDEV PDev)
219 {
220   PPDEV ppdev = (PPDEV)PDev;\r
221
222   // EngDeletePalette(devinfoVGA.hpalDefault);
223   if (ppdev->pjPreallocSSBBuffer != NULL)
224   {
225     EngFreeMem(ppdev->pjPreallocSSBBuffer);
226   }
227
228   if (ppdev->pucDIB4ToVGAConvBuffer != NULL)
229   {
230     EngFreeMem(ppdev->pucDIB4ToVGAConvBuffer);
231   }
232   DPRINT( "Freeing PDEV\n" );
233   EngFreeMem(PDev);
234 }
235
236
237 VOID STDCALL
238 DrvDisableSurface(IN DHPDEV PDev)
239 {
240   PPDEV ppdev = (PPDEV)PDev;
241   PDEVSURF pdsurf = ppdev->AssociatedSurf;
242   PSAVED_SCREEN_BITS pSSB, pSSBNext;
243   CHECKPOINT;
244   DPRINT( "KMDriver: %x\n", ppdev->KMDriver );
245   //  EngFreeMem(pdsurf->BankSelectInfo);
246   CHECKPOINT;
247   if (pdsurf->BankInfo != NULL) {
248     EngFreeMem(pdsurf->BankInfo);
249   }
250   CHECKPOINT;
251   if (pdsurf->BankInfo2RW != NULL) {
252     EngFreeMem(pdsurf->BankInfo2RW);
253   }
254   CHECKPOINT;
255   if (pdsurf->BankBufferPlane0 != NULL) {
256     EngFreeMem(pdsurf->BankBufferPlane0);
257   }
258   CHECKPOINT;
259   if (ppdev->pPointerAttributes != NULL) {
260     EngFreeMem(ppdev->pPointerAttributes);
261   }
262   CHECKPOINT;
263   // free any pending saved screen bit blocks
264 #if 0
265   pSSB = pdsurf->ssbList;
266   while (pSSB != (PSAVED_SCREEN_BITS) NULL) {
267
268     // Point to the next saved screen bits block
269     pSSBNext = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
270
271     // Free the current block
272     EngFreeMem(pSSB);
273     pSSB = pSSBNext;
274     }
275 #endif
276   EngDeleteSurface((HSURF) ppdev->SurfHandle);
277   //  EngFreeMem(pdsurf); // free the surface
278 }
279
280
281 static VOID
282 InitSavedBits(PPDEV ppdev)
283 {
284   if (!(ppdev->fl & DRIVER_OFFSCREEN_REFRESHED))
285   {
286     return;
287   }
288
289   // set up rect to right of visible screen
290   ppdev->SavedBitsRight.left   = ppdev->sizeSurf.cx;
291   ppdev->SavedBitsRight.top    = 0;
292   ppdev->SavedBitsRight.right  = ppdev->sizeMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
293   ppdev->SavedBitsRight.bottom = ppdev->sizeSurf.cy;
294
295   if ((ppdev->SavedBitsRight.right <= ppdev->SavedBitsRight.left) ||
296       (ppdev->SavedBitsRight.bottom <= ppdev->SavedBitsRight.top))
297   {
298     ppdev->SavedBitsRight.left   = 0;
299     ppdev->SavedBitsRight.top    = 0;
300     ppdev->SavedBitsRight.right  = 0;
301     ppdev->SavedBitsRight.bottom = 0;
302   }
303
304   // set up rect below visible screen
305   ppdev->SavedBitsBottom.left   = 0;
306   ppdev->SavedBitsBottom.top    = ppdev->sizeSurf.cy;
307   ppdev->SavedBitsBottom.right  = ppdev->sizeMem.cx-PLANAR_PELS_PER_CPU_ADDRESS;
308   ppdev->SavedBitsBottom.bottom = ppdev->sizeMem.cy - ppdev->NumScansUsedByPointer;
309
310   if ((ppdev->SavedBitsBottom.right <= ppdev->SavedBitsBottom.left) ||
311       (ppdev->SavedBitsBottom.bottom <= ppdev->SavedBitsBottom.top))
312   {
313     ppdev->SavedBitsBottom.left   = 0;
314     ppdev->SavedBitsBottom.top    = 0;
315     ppdev->SavedBitsBottom.right  = 0;
316     ppdev->SavedBitsBottom.bottom = 0;
317   }
318
319   ppdev->BitsSaved = FALSE;
320
321   return;
322 }
323
324
325 HSURF STDCALL
326 DrvEnableSurface(IN DHPDEV PDev)
327 {
328   PPDEV ppdev = (PPDEV)PDev;
329   PDEVSURF pdsurf;
330   DHSURF dhsurf;
331   HSURF hsurf;
332
333   DPRINT1("DrvEnableSurface() called\n");
334
335   // Initialize the VGA
336   if (!VGAInitialized)
337     {
338       if (!InitVGA(ppdev, TRUE))
339         {
340           goto error_done;
341         }
342       VGAInitialized = TRUE;
343     }
344 CHECKPOINT1;
345
346   // dhsurf is of type DEVSURF, which is the drivers specialized surface type
347   dhsurf = (DHSURF)EngAllocMem(0, sizeof(DEVSURF), ALLOC_TAG);
348   if (dhsurf == (DHSURF) 0)
349   {
350     goto error_done;
351   }
352
353   pdsurf = (PDEVSURF) dhsurf;
354   pdsurf->ident         = DEVSURF_IDENT;
355   pdsurf->flSurf        = 0;
356   pdsurf->Format       = BMF_PHYSDEVICE;
357   pdsurf->jReserved1    = 0;
358   pdsurf->jReserved2    = 0;
359   pdsurf->ppdev         = ppdev;
360   pdsurf->sizeSurf.cx   = ppdev->sizeSurf.cx;
361   pdsurf->sizeSurf.cy   = ppdev->sizeSurf.cy;
362   pdsurf->NextPlane    = 0;
363   pdsurf->Scan0       = ppdev->fbScreen;
364   pdsurf->BitmapStart = ppdev->fbScreen;
365   pdsurf->StartBmp      = ppdev->fbScreen;
366
367 /*  pdsurf->Conv          = &ConvertBuffer[0]; */
368
369   if (!InitPointer(ppdev)) {
370       DbgPrint("DrvEnablePDEV failed bInitPointer\n");
371       goto error_clean;
372    }
373
374 /* if (!SetUpBanking(pdsurf, ppdev)) {
375       DISPDBG((0, "DrvEnablePDEV failed SetUpBanking\n"));
376       goto error_clean;
377    } BANKING CODE UNIMPLEMENTED */
378
379   if ((hsurf = EngCreateDeviceSurface(dhsurf, ppdev->sizeSurf, BMF_4BPP)) ==
380       (HSURF)0)
381   {
382     // Call to EngCreateDeviceSurface failed
383     EngDebugPrint("VGADDI:", "EngCreateDeviceSurface call failed\n", 0);
384     goto error_clean;
385   }
386
387   InitSavedBits(ppdev);
388
389   if (EngAssociateSurface(hsurf, ppdev->GDIDevHandle, HOOK_BITBLT | HOOK_PAINT | HOOK_LINETO | HOOK_COPYBITS |
390     HOOK_TRANSPARENTBLT))
391   {
392     EngDebugPrint("VGADDI:", "Successfully associated surface\n", 0);
393     ppdev->SurfHandle = hsurf;
394     ppdev->AssociatedSurf = pdsurf;
395
396     // Set up an empty saved screen block list
397     pdsurf->ssbList = NULL;
398
399     return(hsurf);
400   }
401   DPRINT( "EngAssociateSurface() failed\n" );
402   EngDeleteSurface(hsurf);
403
404 error_clean:
405    EngFreeMem(dhsurf);
406
407 error_done:
408    return((HSURF)0);
409 }
410
411
412 ULONG STDCALL
413 DrvGetModes(IN HANDLE Driver,
414             IN ULONG DataSize,
415             OUT PDEVMODEW DM)
416 {
417   DWORD NumModes;
418   DWORD ModeSize;
419   DWORD OutputSize;
420   DWORD OutputModes = DataSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
421   PVIDEO_MODE_INFORMATION VideoModeInformation, VideoTemp;
422
423   NumModes = getAvailableModes(Driver,
424                                (PVIDEO_MODE_INFORMATION *) &VideoModeInformation,
425                                &ModeSize);
426
427   if (NumModes == 0)
428   {
429     return 0;
430   }
431
432   if (DM == NULL)
433   {
434     OutputSize = NumModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
435   } else {
436
437     OutputSize=0;
438     VideoTemp = VideoModeInformation;
439
440     do
441     {
442       if (VideoTemp->Length != 0)
443       {
444         if (OutputModes == 0)
445         {
446           break;
447         }
448
449         memset(DM, 0, sizeof(DEVMODEW));
450         memcpy(DM->dmDeviceName, DLL_NAME, sizeof(DLL_NAME));
451
452         DM->dmSpecVersion      = DM_SPECVERSION;
453         DM->dmDriverVersion    = DM_SPECVERSION;
454         DM->dmSize             = sizeof(DEVMODEW);
455         DM->dmDriverExtra      = DRIVER_EXTRA_SIZE;
456         DM->dmBitsPerPel       = VideoTemp->NumberOfPlanes *
457                                  VideoTemp->BitsPerPlane;
458         DM->dmPelsWidth        = VideoTemp->VisScreenWidth;
459         DM->dmPelsHeight       = VideoTemp->VisScreenHeight;
460         DM->dmDisplayFrequency = VideoTemp->Frequency;
461         DM->dmDisplayFlags     = 0;
462
463         DM->dmFields           = DM_BITSPERPEL       |
464                                  DM_PELSWIDTH        |
465                                  DM_PELSHEIGHT       |
466                                  DM_DISPLAYFREQUENCY |
467                                  DM_DISPLAYFLAGS     ;
468
469         // next DEVMODE entry
470         OutputModes--;
471
472         DM = (PDEVMODEW) ( ((ULONG)DM) + sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
473
474         OutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
475       }
476
477       VideoTemp = (PVIDEO_MODE_INFORMATION)(((PUCHAR)VideoTemp) + ModeSize);
478
479     } while (--NumModes);
480   }
481 }
482
483 /* EOF */