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