Reactos

[WIN32SS:ENG] Rework EngpUpdateGraphicsDeviceList

- choose VGA adapter outside of driver initialization loop
- choose primary adapter outside of driver initialization loop
- link VGA adapter to primary adapter at the end
- only set DISPLAY_DEVICE_PRIMARY_DEVICE in this function

Also mark VgaSave driver as SystemStart instead of Disabled,
so it is available if main display driver doesn't work.

+64 -47
-3
boot/bootdata/hiveinst.inf
··· 7 7 ; 8 8 ; Display driver section 9 9 ; 10 - 11 - ; VGA miniport driver 12 - HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Start",0x00010001,0x00000001
+1 -1
win32ss/drivers/miniport/vga/vga_reg.inf
··· 3 3 HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","ErrorControl",0x00010001,0x00000000 4 4 HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Group",0x00000000,"Video Save" 5 5 HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","ImagePath",0x00020000,"system32\drivers\vga.sys" 6 - HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Start",0x00010001,0x00000004 6 + HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Start",0x00010001,0x00000001 7 7 HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Type",0x00010001,0x00000001 8 8 HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave","Tag",0x00010001,0x00000002 9 9 HKLM,"SYSTEM\CurrentControlSet\Services\VgaSave\Video","Service",0x00000000,"VgaSave"
+62 -42
win32ss/gdi/eng/device.c
··· 170 170 } 171 171 } 172 172 173 + /* Goal of this function is to: 174 + * - detect new graphic devices (from registry) and initialize them 175 + * - link primary device and VGA device (if available) using pVgaDevice field 176 + * - handle gbBaseVideo global flag 177 + * - set DISPLAY_DEVICE_PRIMARY_DEVICE on at least one device 178 + * - set gpPrimaryGraphicsDevice 179 + * - set gpVgaGraphicsDevice 180 + */ 173 181 NTSTATUS 174 182 EngpUpdateGraphicsDeviceList(VOID) 175 183 { 176 - ULONG iDevNum, iVGACompatible = -1, ulMaxObjectNumber = 0; 184 + ULONG iDevNum, ulMaxObjectNumber = 0; 177 185 WCHAR awcDeviceName[20], awcWinDeviceName[20]; 178 186 UNICODE_STRING ustrDeviceName; 179 187 WCHAR awcBuffer[256]; 180 188 NTSTATUS Status; 181 - PGRAPHICS_DEVICE pGraphicsDevice; 182 - BOOLEAN bFoundNewDevice = FALSE; 189 + PGRAPHICS_DEVICE pGraphicsDevice, pNewPrimaryGraphicsDevice = NULL; 183 190 ULONG cbValue; 184 191 HKEY hkey; 185 192 ··· 191 198 return Status; 192 199 } 193 200 194 - /* Read the name of the VGA adapter */ 195 - cbValue = sizeof(awcDeviceName); 196 - Status = RegQueryValue(hkey, L"VgaCompatible", REG_SZ, awcDeviceName, &cbValue); 197 - if (NT_SUCCESS(Status)) 198 - { 199 - iVGACompatible = _wtoi(&awcDeviceName[sizeof("\\Device\\Video")-1]); 200 - ERR("VGA adapter = %lu\n", iVGACompatible); 201 - } 202 - 203 201 /* Get the maximum number of adapters */ 204 202 if (!RegReadDWORD(hkey, L"MaxObjectNumber", &ulMaxObjectNumber)) 205 203 { ··· 208 206 209 207 TRACE("Found %lu devices\n", ulMaxObjectNumber + 1); 210 208 211 - /* Loop through all adapters */ 209 + /* Loop through all adapters, to detect new ones */ 212 210 for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++) 213 211 { 214 212 /* Create the adapter's key name */ ··· 237 235 /* Initialize the driver for this device */ 238 236 pGraphicsDevice = InitDisplayDriver(awcDeviceName, awcBuffer); 239 237 if (!pGraphicsDevice) continue; 240 - 241 - /* Check if this is a VGA compatible adapter */ 242 - if (pGraphicsDevice->StateFlags & DISPLAY_DEVICE_VGA_COMPATIBLE) 243 - { 244 - /* Save this as the VGA adapter */ 245 - if (!gpVgaGraphicsDevice || !EngpHasVgaDriver(gpVgaGraphicsDevice)) 246 - { 247 - gpVgaGraphicsDevice = pGraphicsDevice; 248 - TRACE("gpVgaGraphicsDevice = %p\n", gpVgaGraphicsDevice); 249 - } 250 - } 251 - bFoundNewDevice = TRUE; 252 - 253 - /* Set the first one as primary device */ 254 - if (!gpPrimaryGraphicsDevice || EngpHasVgaDriver(gpPrimaryGraphicsDevice)) 255 - { 256 - gpPrimaryGraphicsDevice = pGraphicsDevice; 257 - TRACE("gpPrimaryGraphicsDevice = %p\n", gpPrimaryGraphicsDevice); 258 - } 259 238 } 260 239 261 240 /* Close the device map registry key */ 262 241 ZwClose(hkey); 263 242 264 - /* Can we link VGA device to primary device? */ 265 - if (gpPrimaryGraphicsDevice && 266 - gpVgaGraphicsDevice && 267 - gpPrimaryGraphicsDevice != gpVgaGraphicsDevice && 268 - !gpPrimaryGraphicsDevice->pVgaDevice) 243 + /* Choose a VGA device */ 244 + /* Try a device with DISPLAY_DEVICE_VGA_COMPATIBLE flag. If not found, 245 + * fall back to current VGA device */ 246 + for (pGraphicsDevice = gpGraphicsDeviceFirst; 247 + pGraphicsDevice; 248 + pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice) 269 249 { 270 - /* Yes. Remove VGA device from global list, and attach it to primary device */ 271 - TRACE("Linking VGA device %S to primary device %S\n", gpVgaGraphicsDevice->szNtDeviceName, gpPrimaryGraphicsDevice->szNtDeviceName); 272 - EngpUnlinkGraphicsDevice(gpVgaGraphicsDevice); 273 - gpPrimaryGraphicsDevice->pVgaDevice = gpVgaGraphicsDevice; 250 + if (pGraphicsDevice == gpVgaGraphicsDevice) 251 + continue; 252 + if (pGraphicsDevice->StateFlags & DISPLAY_DEVICE_VGA_COMPATIBLE && EngpHasVgaDriver(pGraphicsDevice)) 253 + { 254 + gpVgaGraphicsDevice = pGraphicsDevice; 255 + break; 256 + } 274 257 } 275 258 276 - if (bFoundNewDevice && gbBaseVideo) 259 + /* Handle gbBaseVideo */ 260 + if (gbBaseVideo) 277 261 { 278 262 PGRAPHICS_DEVICE pToDelete; 279 263 ··· 304 288 } 305 289 306 290 /* Unlock list */ 291 + EngReleaseSemaphore(ghsemGraphicsDeviceList); 292 + } 293 + 294 + /* Choose a primary device (if none already exists) */ 295 + if (!gpPrimaryGraphicsDevice) 296 + { 297 + for (pGraphicsDevice = gpGraphicsDeviceFirst; 298 + pGraphicsDevice; 299 + pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice) 300 + { 301 + if (!EngpHasVgaDriver(pGraphicsDevice)) 302 + { 303 + pNewPrimaryGraphicsDevice = pGraphicsDevice; 304 + break; 305 + } 306 + } 307 + if (!pNewPrimaryGraphicsDevice) 308 + pNewPrimaryGraphicsDevice = gpGraphicsDeviceFirst; 309 + if (pNewPrimaryGraphicsDevice) 310 + { 311 + pNewPrimaryGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE; 312 + gpPrimaryGraphicsDevice = pNewPrimaryGraphicsDevice; 313 + } 314 + } 315 + 316 + /* Can we link VGA device to primary device? */ 317 + if (gpPrimaryGraphicsDevice && 318 + gpVgaGraphicsDevice && 319 + gpPrimaryGraphicsDevice != gpVgaGraphicsDevice && 320 + !gpPrimaryGraphicsDevice->pVgaDevice) 321 + { 322 + /* Yes. Remove VGA device from global list, and attach it to primary device */ 323 + TRACE("Linking VGA device %S to primary device %S\n", gpVgaGraphicsDevice->szNtDeviceName, gpPrimaryGraphicsDevice->szNtDeviceName); 324 + EngAcquireSemaphore(ghsemGraphicsDeviceList); 325 + EngpUnlinkGraphicsDevice(gpVgaGraphicsDevice); 326 + gpPrimaryGraphicsDevice->pVgaDevice = gpVgaGraphicsDevice; 307 327 EngReleaseSemaphore(ghsemGraphicsDeviceList); 308 328 } 309 329
+1 -1
win32ss/gdi/eng/pdevobj.c
··· 547 547 { 548 548 RtlCopyMemory(ppdev->pdmwDev, pdm, pdm->dmSize + pdm->dmDriverExtra); 549 549 /* FIXME: this must be done in a better way */ 550 - pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE | DISPLAY_DEVICE_ATTACHED_TO_DESKTOP; 550 + pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP; 551 551 } 552 552 } 553 553