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