1 /* 2 * PROJECT: ReactOS Framebuffer Display Driver 3 * LICENSE: Microsoft NT4 DDK Sample Code License 4 * FILE: win32ss/drivers/displays/vga_new/enable.c 5 * PURPOSE: Main Driver Initialization and PDEV Enabling 6 * PROGRAMMERS: Copyright (c) 1992-1995 Microsoft Corporation 7 * ReactOS Portable Systems Group 8 */ 9 10 #include "driver.h" 11 12 // The driver function table with all function index/address pairs 13 14 static DRVFN gadrvfn[] = 15 { 16 { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV }, 17 { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV }, 18 { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV }, 19 { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface }, 20 { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface }, 21 { INDEX_DrvAssertMode, (PFN) DrvAssertMode }, 22 // eVb: 1.2 [VGARISC Change] - Disable hardware palette support 23 { INDEX_DrvSetPalette, (PFN) DrvSetPalette }, 24 // eVb: 1.2 [END] 25 // eVb: 1.1 [VGARISC Change] - Disable hardware pointer support 26 #if 0 27 { INDEX_DrvMovePointer, (PFN) DrvMovePointer }, 28 { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape }, 29 #endif 30 // eVb: 1.1 [END] 31 { INDEX_DrvGetModes, (PFN) DrvGetModes } 32 }; 33 34 // Define the functions you want to hook for 8/16/24/32 pel formats 35 36 #define HOOKS_BMF8BPP 0 37 38 #define HOOKS_BMF16BPP 0 39 40 #define HOOKS_BMF24BPP 0 41 42 #define HOOKS_BMF32BPP 0 43 44 /******************************Public*Routine******************************\ 45 * DrvEnableDriver 46 * 47 * Enables the driver by retrieving the drivers function table and version. 48 * 49 \**************************************************************************/ 50 51 BOOL APIENTRY DrvEnableDriver( 52 ULONG iEngineVersion, 53 ULONG cj, 54 PDRVENABLEDATA pded) 55 { 56 // Engine Version is passed down so future drivers can support previous 57 // engine versions. A next generation driver can support both the old 58 // and new engine conventions if told what version of engine it is 59 // working with. For the first version the driver does nothing with it. 60 // eVb: 1.1 [DDK Change] - Remove bogus statement 61 //iEngineVersion; 62 // eVb: 1.1 [END] 63 // Fill in as much as we can. 64 65 if (cj >= sizeof(DRVENABLEDATA)) 66 pded->pdrvfn = gadrvfn; 67 68 if (cj >= (sizeof(ULONG) * 2)) 69 pded->c = sizeof(gadrvfn) / sizeof(DRVFN); 70 71 // DDI version this driver was targeted for is passed back to engine. 72 // Future graphic's engine may break calls down to old driver format. 73 74 if (cj >= sizeof(ULONG)) 75 // eVb: 1.2 [DDK Change] - Use DDI_DRIVER_VERSION_NT4 instead of DDI_DRIVER_VERSION 76 pded->iDriverVersion = DDI_DRIVER_VERSION_NT4; 77 // eVb: 1.2 [END] 78 79 return TRUE; 80 } 81 82 /******************************Public*Routine******************************\ 83 * DrvEnablePDEV 84 * 85 * DDI function, Enables the Physical Device. 86 * 87 * Return Value: device handle to pdev. 88 * 89 \**************************************************************************/ 90 91 DHPDEV APIENTRY DrvEnablePDEV( 92 DEVMODEW *pDevmode, // Pointer to DEVMODE 93 PWSTR pwszLogAddress, // Logical address 94 ULONG cPatterns, // number of patterns 95 HSURF *ahsurfPatterns, // return standard patterns 96 ULONG cjGdiInfo, // Length of memory pointed to by pGdiInfo 97 ULONG *pGdiInfo, // Pointer to GdiInfo structure 98 ULONG cjDevInfo, // Length of following PDEVINFO structure 99 DEVINFO *pDevInfo, // physical device information structure 100 HDEV hdev, // HDEV, used for callbacks 101 PWSTR pwszDeviceName, // DeviceName - not used 102 HANDLE hDriver) // Handle to base driver 103 { 104 GDIINFO GdiInfo; 105 DEVINFO DevInfo; 106 PPDEV ppdev = NULL; 107 108 UNREFERENCED_PARAMETER(pwszLogAddress); 109 UNREFERENCED_PARAMETER(pwszDeviceName); 110 111 // Allocate a physical device structure. 112 113 ppdev = (PPDEV) EngAllocMem(0, sizeof(PDEV), ALLOC_TAG); 114 115 if (ppdev == NULL) 116 { 117 RIP("DISP DrvEnablePDEV failed EngAllocMem\n"); 118 return NULL; 119 } 120 121 memset(ppdev, 0, sizeof(PDEV)); 122 123 // Save the screen handle in the PDEV. 124 125 ppdev->hDriver = hDriver; 126 127 // Get the current screen mode information. Set up device caps and devinfo. 128 129 if (!bInitPDEV(ppdev, pDevmode, &GdiInfo, &DevInfo)) 130 { 131 DISPDBG((0,"DISP DrvEnablePDEV failed\n")); 132 goto error_free; 133 } 134 135 // eVb: 1.2 [VGARISC Change] - Disable hardware pointer support 136 #if 0 137 // Initialize the cursor information. 138 139 if (!bInitPointer(ppdev, &DevInfo)) 140 { 141 // Not a fatal error... 142 DISPDBG((0, "DrvEnablePDEV failed bInitPointer\n")); 143 } 144 145 #endif 146 // eVb: 1.2 [END] 147 // Initialize palette information. 148 149 if (!bInitPaletteInfo(ppdev, &DevInfo)) 150 { 151 RIP("DrvEnablePDEV failed bInitPalette\n"); 152 goto error_free; 153 } 154 155 // Copy the devinfo into the engine buffer. 156 157 memcpy(pDevInfo, &DevInfo, min(sizeof(DEVINFO), cjDevInfo)); 158 159 // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this 160 // pdev. 161 162 memcpy(pGdiInfo, &GdiInfo, min(cjGdiInfo, sizeof(GDIINFO))); 163 164 return (DHPDEV)ppdev; 165 166 // Error case for failure. 167 error_free: 168 EngFreeMem(ppdev); 169 return NULL; 170 } 171 172 /******************************Public*Routine******************************\ 173 * DrvCompletePDEV 174 * 175 * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV. 176 * 177 \**************************************************************************/ 178 179 VOID APIENTRY DrvCompletePDEV( 180 DHPDEV dhpdev, 181 HDEV hdev) 182 { 183 ((PPDEV) dhpdev)->hdevEng = hdev; 184 } 185 186 /******************************Public*Routine******************************\ 187 * DrvDisablePDEV 188 * 189 * Release the resources allocated in DrvEnablePDEV. If a surface has been 190 * enabled DrvDisableSurface will have already been called. 191 * 192 \**************************************************************************/ 193 194 VOID APIENTRY DrvDisablePDEV( 195 DHPDEV dhpdev) 196 { 197 vDisablePalette((PPDEV) dhpdev); 198 EngFreeMem(dhpdev); 199 } 200 201 /******************************Public*Routine******************************\ 202 * DrvEnableSurface 203 * 204 * Enable the surface for the device. Hook the calls this driver supports. 205 * 206 * Return: Handle to the surface if successful, 0 for failure. 207 * 208 \**************************************************************************/ 209 210 HSURF APIENTRY DrvEnableSurface( 211 DHPDEV dhpdev) 212 { 213 PPDEV ppdev; 214 HSURF hsurf; 215 SIZEL sizl; 216 ULONG ulBitmapType; 217 #if 0 218 FLONG flHooks; 219 #endif 220 HSURF hSurfBitmap; 221 222 // Create engine bitmap around frame buffer. 223 224 ppdev = (PPDEV) dhpdev; 225 226 if (!bInitSURF(ppdev, TRUE)) 227 { 228 RIP("DISP DrvEnableSurface failed bInitSURF\n"); 229 return NULL; 230 } 231 232 sizl.cx = ppdev->cxScreen; 233 sizl.cy = ppdev->cyScreen; 234 235 // eVb: 1.3 [VGARISC Change] - Disable dynamic palette and > 4BPP support 236 #if 0 237 if (ppdev->ulBitCount == 8) 238 { 239 if (!bInit256ColorPalette(ppdev)) { 240 RIP("DISP DrvEnableSurface failed to init the 8bpp palette\n"); 241 return NULL; 242 } 243 ulBitmapType = BMF_8BPP; 244 flHooks = HOOKS_BMF8BPP; 245 } 246 else if (ppdev->ulBitCount == 16) 247 { 248 ulBitmapType = BMF_16BPP; 249 flHooks = HOOKS_BMF16BPP; 250 } 251 else if (ppdev->ulBitCount == 24) 252 { 253 ulBitmapType = BMF_24BPP; 254 flHooks = HOOKS_BMF24BPP; 255 } 256 else 257 { 258 ulBitmapType = BMF_32BPP; 259 flHooks = HOOKS_BMF32BPP; 260 } 261 // eVb: 1.3 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping 262 ppdev->flHooks = flHooks; 263 // eVb: 1.3 [END] 264 #else 265 ulBitmapType = BMF_4BPP; 266 #endif 267 // eVb: 1.3 [END] 268 // eVb: 1.4 [DDK Change] - Use EngCreateDeviceSurface instead of EngCreateBitmap 269 hsurf = (HSURF)EngCreateDeviceSurface((DHSURF)ppdev, 270 sizl, 271 ulBitmapType); 272 273 if (hsurf == NULL) 274 { 275 RIP("DISP DrvEnableSurface failed EngCreateDeviceSurface\n"); 276 return NULL; 277 } 278 // eVb: 1.4 [END] 279 280 // eVb: 1.5 [DDK Change] - Use EngModifySurface instead of EngAssociateSurface 281 if ( !EngModifySurface(hsurf, 282 ppdev->hdevEng, 283 ppdev->flHooks | HOOK_SYNCHRONIZE, 284 MS_NOTSYSTEMMEMORY, 285 (DHSURF)ppdev, 286 ppdev->pjScreen, 287 ppdev->lDeltaScreen, 288 NULL)) 289 { 290 RIP("DISP DrvEnableSurface failed EngModifySurface\n"); 291 return NULL; 292 } 293 // eVb: 1.5 [END] 294 ppdev->hsurfEng = hsurf; 295 // eVb: 1.4 [VGARISC Change] - Allocate 4BPP DIB that will store GDI drawing 296 hSurfBitmap = (HSURF)EngCreateBitmap(sizl, 0, ulBitmapType, 0, NULL); 297 if (hSurfBitmap == NULL) 298 { 299 RIP("DISP DrvEnableSurface failed EngCreateBitmap\n"); 300 return NULL; 301 } 302 303 if ( !EngModifySurface(hSurfBitmap, 304 ppdev->hdevEng, 305 ppdev->flHooks | HOOK_SYNCHRONIZE, 306 MS_NOTSYSTEMMEMORY, 307 (DHSURF)ppdev, 308 ppdev->pjScreen, 309 ppdev->lDeltaScreen, 310 NULL)) 311 { 312 RIP("DISP DrvEnableSurface failed second EngModifySurface\n"); 313 return NULL; 314 } 315 316 ppdev->pso = EngLockSurface(hSurfBitmap); 317 if (ppdev->pso == NULL) 318 { 319 RIP("DISP DrvEnableSurface failed EngLockSurface\n"); 320 return NULL; 321 } 322 // eVb: 1.4 [END] 323 return hsurf; 324 } 325 326 /******************************Public*Routine******************************\ 327 * DrvDisableSurface 328 * 329 * Free resources allocated by DrvEnableSurface. Release the surface. 330 * 331 \**************************************************************************/ 332 333 VOID APIENTRY DrvDisableSurface( 334 DHPDEV dhpdev) 335 { 336 EngDeleteSurface(((PPDEV) dhpdev)->hsurfEng); 337 vDisableSURF((PPDEV) dhpdev); 338 ((PPDEV) dhpdev)->hsurfEng = NULL; 339 } 340 341 /******************************Public*Routine******************************\ 342 * DrvAssertMode 343 * 344 * This asks the device to reset itself to the mode of the pdev passed in. 345 * 346 \**************************************************************************/ 347 348 BOOL APIENTRY DrvAssertMode( 349 DHPDEV dhpdev, 350 BOOL bEnable) 351 { 352 PPDEV ppdev = (PPDEV) dhpdev; 353 ULONG ulReturn; 354 PBYTE pjScreen; 355 356 if (bEnable) 357 { 358 // 359 // The screen must be reenabled, reinitialize the device to clean state. 360 // 361 // eVb: 1.6 [DDK Change] - Support new VGA Miniport behavior w.r.t updated framebuffer remapping 362 pjScreen = ppdev->pjScreen; 363 364 if (!bInitSURF(ppdev, FALSE)) 365 { 366 DISPDBG((0, "DISP DrvAssertMode failed bInitSURF\n")); 367 return (FALSE); 368 } 369 370 if (pjScreen != ppdev->pjScreen) { 371 372 if ( !EngModifySurface(ppdev->hsurfEng, 373 ppdev->hdevEng, 374 ppdev->flHooks | HOOK_SYNCHRONIZE, 375 MS_NOTSYSTEMMEMORY, 376 (DHSURF)ppdev, 377 ppdev->pjScreen, 378 ppdev->lDeltaScreen, 379 NULL)) 380 { 381 DISPDBG((0, "DISP DrvAssertMode failed EngModifySurface\n")); 382 return (FALSE); 383 } 384 } 385 // eVb: 1.6 [END] 386 return (TRUE); 387 } 388 else 389 { 390 // 391 // We must give up the display. 392 // Call the kernel driver to reset the device to a known state. 393 // 394 395 if (EngDeviceIoControl(ppdev->hDriver, 396 IOCTL_VIDEO_RESET_DEVICE, 397 NULL, 398 0, 399 NULL, 400 0, 401 &ulReturn)) 402 { 403 RIP("DISP DrvAssertMode failed IOCTL"); 404 return FALSE; 405 } 406 else 407 { 408 return TRUE; 409 } 410 } 411 } 412 413 /******************************Public*Routine******************************\ 414 * DrvGetModes 415 * 416 * Returns the list of available modes for the device. 417 * 418 \**************************************************************************/ 419 420 ULONG APIENTRY DrvGetModes( 421 HANDLE hDriver, 422 ULONG cjSize, 423 DEVMODEW *pdm) 424 425 { 426 427 DWORD cModes; 428 DWORD cbOutputSize; 429 PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp; 430 DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE); 431 DWORD cbModeSize; 432 433 DISPDBG((3, "DrvGetModes\n")); 434 435 cModes = getAvailableModes(hDriver, 436 (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation, 437 &cbModeSize); 438 439 if (cModes == 0) 440 { 441 DISPDBG((0, "DrvGetModes failed to get mode information")); 442 return 0; 443 } 444 445 if (pdm == NULL) 446 { 447 cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE); 448 } 449 else 450 { 451 // 452 // Now copy the information for the supported modes back into the output 453 // buffer 454 // 455 456 cbOutputSize = 0; 457 458 pVideoTemp = pVideoModeInformation; 459 460 do 461 { 462 if (pVideoTemp->Length != 0) 463 { 464 if (cOutputModes == 0) 465 { 466 break; 467 } 468 469 // 470 // Zero the entire structure to start off with. 471 // 472 473 memset(pdm, 0, sizeof(DEVMODEW)); 474 475 // 476 // Set the name of the device to the name of the DLL. 477 // 478 479 memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME)); 480 481 pdm->dmSpecVersion = DM_SPECVERSION; 482 pdm->dmDriverVersion = DM_SPECVERSION; 483 pdm->dmSize = sizeof(DEVMODEW); 484 pdm->dmDriverExtra = DRIVER_EXTRA_SIZE; 485 486 pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes * 487 pVideoTemp->BitsPerPlane; 488 pdm->dmPelsWidth = pVideoTemp->VisScreenWidth; 489 pdm->dmPelsHeight = pVideoTemp->VisScreenHeight; 490 pdm->dmDisplayFrequency = pVideoTemp->Frequency; 491 pdm->dmDisplayFlags = 0; 492 493 pdm->dmFields = DM_BITSPERPEL | 494 DM_PELSWIDTH | 495 DM_PELSHEIGHT | 496 DM_DISPLAYFREQUENCY | 497 DM_DISPLAYFLAGS ; 498 499 // 500 // Go to the next DEVMODE entry in the buffer. 501 // 502 503 cOutputModes--; 504 505 pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) + 506 DRIVER_EXTRA_SIZE); 507 508 cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE); 509 510 } 511 512 pVideoTemp = (PVIDEO_MODE_INFORMATION) 513 (((PUCHAR)pVideoTemp) + cbModeSize); 514 515 } while (--cModes); 516 } 517 518 EngFreeMem(pVideoModeInformation); 519 520 return cbOutputSize; 521 522 } 523