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