1 /* 2 * ReactOS Generic Framebuffer display driver 3 * 4 * Copyright (C) 2004 Filip Navara 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #include "framebuf.h" 22 23 static LOGFONTW SystemFont = { 16, 7, 0, 0, 700, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_DONTCARE, L"System" }; 24 static LOGFONTW AnsiVariableFont = { 12, 9, 0, 0, 400, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_STROKE_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_DONTCARE, L"MS Sans Serif" }; 25 static LOGFONTW AnsiFixedFont = { 12, 9, 0, 0, 400, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_STROKE_PRECIS, PROOF_QUALITY, FIXED_PITCH | FF_DONTCARE, L"Courier" }; 26 27 /* 28 * GetAvailableModes 29 * 30 * Calls the miniport to get the list of modes supported by the kernel driver, 31 * and returns the list of modes supported by the display driver. 32 */ 33 34 DWORD 35 GetAvailableModes( 36 HANDLE hDriver, 37 PVIDEO_MODE_INFORMATION *ModeInfo, 38 DWORD *ModeInfoSize) 39 { 40 ULONG ulTemp; 41 VIDEO_NUM_MODES Modes; 42 PVIDEO_MODE_INFORMATION ModeInfoPtr; 43 44 /* 45 * Get the number of modes supported by the mini-port 46 */ 47 48 if (EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES, NULL, 49 0, &Modes, sizeof(VIDEO_NUM_MODES), &ulTemp)) 50 { 51 return 0; 52 } 53 54 if (Modes.NumModes == 0) 55 { 56 return 0; 57 } 58 59 *ModeInfoSize = Modes.ModeInformationLength; 60 61 /* 62 * Allocate the buffer for the miniport to write the modes in. 63 */ 64 65 *ModeInfo = (PVIDEO_MODE_INFORMATION)EngAllocMem(0, Modes.NumModes * 66 Modes.ModeInformationLength, ALLOC_TAG); 67 68 if (*ModeInfo == NULL) 69 { 70 return 0; 71 } 72 73 /* 74 * Ask the miniport to fill in the available modes. 75 */ 76 77 if (EngDeviceIoControl(hDriver, IOCTL_VIDEO_QUERY_AVAIL_MODES, NULL, 0, 78 *ModeInfo, Modes.NumModes * Modes.ModeInformationLength, 79 &ulTemp)) 80 { 81 EngFreeMem(*ModeInfo); 82 *ModeInfo = NULL; 83 return 0; 84 } 85 86 /* 87 * Now see which of these modes are supported by the display driver. 88 * As an internal mechanism, set the length to 0 for the modes we 89 * DO NOT support. 90 */ 91 92 ulTemp = Modes.NumModes; 93 ModeInfoPtr = *ModeInfo; 94 95 /* 96 * Mode is rejected if it is not one plane, or not graphics, or is not 97 * one of 8, 16 or 32 bits per pel. 98 */ 99 100 while (ulTemp--) 101 { 102 if ((ModeInfoPtr->NumberOfPlanes != 1) || 103 !(ModeInfoPtr->AttributeFlags & VIDEO_MODE_GRAPHICS) || 104 ((ModeInfoPtr->BitsPerPlane != 8) && 105 (ModeInfoPtr->BitsPerPlane != 16) && 106 (ModeInfoPtr->BitsPerPlane != 24) && 107 (ModeInfoPtr->BitsPerPlane != 32))) 108 { 109 ModeInfoPtr->Length = 0; 110 } 111 112 ModeInfoPtr = (PVIDEO_MODE_INFORMATION) 113 (((PUCHAR)ModeInfoPtr) + Modes.ModeInformationLength); 114 } 115 116 return Modes.NumModes; 117 } 118 119 BOOL 120 IntInitScreenInfo( 121 PPDEV ppdev, 122 LPDEVMODEW pDevMode, 123 PGDIINFO pGdiInfo, 124 PDEVINFO pDevInfo) 125 { 126 ULONG ModeCount; 127 ULONG ModeInfoSize; 128 PVIDEO_MODE_INFORMATION ModeInfo, ModeInfoPtr, SelectedMode = NULL; 129 VIDEO_COLOR_CAPABILITIES ColorCapabilities; 130 ULONG Temp; 131 132 /* 133 * Call miniport to get information about video modes. 134 */ 135 136 ModeCount = GetAvailableModes(ppdev->hDriver, &ModeInfo, &ModeInfoSize); 137 if (ModeCount == 0) 138 { 139 return FALSE; 140 } 141 142 /* 143 * Select the video mode depending on the info passed in pDevMode. 144 */ 145 146 if (pDevMode->dmPelsWidth == 0 && pDevMode->dmPelsHeight == 0 && 147 pDevMode->dmBitsPerPel == 0 && pDevMode->dmDisplayFrequency == 0) 148 { 149 ModeInfoPtr = ModeInfo; 150 while (ModeCount-- > 0) 151 { 152 if (ModeInfoPtr->Length == 0) 153 { 154 ModeInfoPtr = (PVIDEO_MODE_INFORMATION) 155 (((PUCHAR)ModeInfoPtr) + ModeInfoSize); 156 continue; 157 } 158 SelectedMode = ModeInfoPtr; 159 break; 160 } 161 } 162 else 163 { 164 ModeInfoPtr = ModeInfo; 165 while (ModeCount-- > 0) 166 { 167 if (ModeInfoPtr->Length > 0 && 168 pDevMode->dmPelsWidth == ModeInfoPtr->VisScreenWidth && 169 pDevMode->dmPelsHeight == ModeInfoPtr->VisScreenHeight && 170 pDevMode->dmBitsPerPel == (ModeInfoPtr->BitsPerPlane * 171 ModeInfoPtr->NumberOfPlanes) && 172 pDevMode->dmDisplayFrequency == ModeInfoPtr->Frequency) 173 { 174 SelectedMode = ModeInfoPtr; 175 break; 176 } 177 178 ModeInfoPtr = (PVIDEO_MODE_INFORMATION) 179 (((PUCHAR)ModeInfoPtr) + ModeInfoSize); 180 } 181 } 182 183 if (SelectedMode == NULL) 184 { 185 EngFreeMem(ModeInfo); 186 return FALSE; 187 } 188 189 /* 190 * Fill in the GDIINFO data structure with the information returned from 191 * the kernel driver. 192 */ 193 194 ppdev->ModeIndex = SelectedMode->ModeIndex; 195 ppdev->ScreenWidth = SelectedMode->VisScreenWidth; 196 ppdev->ScreenHeight = SelectedMode->VisScreenHeight; 197 ppdev->ScreenDelta = SelectedMode->ScreenStride; 198 ppdev->BitsPerPixel = (UCHAR)(SelectedMode->BitsPerPlane * SelectedMode->NumberOfPlanes); 199 200 ppdev->MemWidth = SelectedMode->VideoMemoryBitmapWidth; 201 ppdev->MemHeight = SelectedMode->VideoMemoryBitmapHeight; 202 203 ppdev->RedMask = SelectedMode->RedMask; 204 ppdev->GreenMask = SelectedMode->GreenMask; 205 ppdev->BlueMask = SelectedMode->BlueMask; 206 207 pGdiInfo->ulVersion = GDI_DRIVER_VERSION; 208 pGdiInfo->ulTechnology = DT_RASDISPLAY; 209 pGdiInfo->ulHorzSize = SelectedMode->XMillimeter; 210 pGdiInfo->ulVertSize = SelectedMode->YMillimeter; 211 pGdiInfo->ulHorzRes = SelectedMode->VisScreenWidth; 212 pGdiInfo->ulVertRes = SelectedMode->VisScreenHeight; 213 pGdiInfo->ulPanningHorzRes = SelectedMode->VisScreenWidth; 214 pGdiInfo->ulPanningVertRes = SelectedMode->VisScreenHeight; 215 pGdiInfo->cBitsPixel = SelectedMode->BitsPerPlane; 216 pGdiInfo->cPlanes = SelectedMode->NumberOfPlanes; 217 pGdiInfo->ulVRefresh = SelectedMode->Frequency; 218 pGdiInfo->ulBltAlignment = 1; 219 pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels; 220 pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels; 221 pGdiInfo->flTextCaps = TC_RA_ABLE; 222 pGdiInfo->flRaster = 0; 223 pGdiInfo->ulDACRed = SelectedMode->NumberRedBits; 224 pGdiInfo->ulDACGreen = SelectedMode->NumberGreenBits; 225 pGdiInfo->ulDACBlue = SelectedMode->NumberBlueBits; 226 pGdiInfo->ulAspectX = 0x24; 227 pGdiInfo->ulAspectY = 0x24; 228 pGdiInfo->ulAspectXY = 0x33; 229 pGdiInfo->xStyleStep = 1; 230 pGdiInfo->yStyleStep = 1; 231 pGdiInfo->denStyleStep = 3; 232 pGdiInfo->ptlPhysOffset.x = 0; 233 pGdiInfo->ptlPhysOffset.y = 0; 234 pGdiInfo->szlPhysSize.cx = 0; 235 pGdiInfo->szlPhysSize.cy = 0; 236 237 /* 238 * Try to get the color info from the miniport. 239 */ 240 241 if (!EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES, 242 NULL, 0, &ColorCapabilities, 243 sizeof(VIDEO_COLOR_CAPABILITIES), &Temp)) 244 { 245 pGdiInfo->ciDevice.Red.x = ColorCapabilities.RedChromaticity_x; 246 pGdiInfo->ciDevice.Red.y = ColorCapabilities.RedChromaticity_y; 247 pGdiInfo->ciDevice.Green.x = ColorCapabilities.GreenChromaticity_x; 248 pGdiInfo->ciDevice.Green.y = ColorCapabilities.GreenChromaticity_y; 249 pGdiInfo->ciDevice.Blue.x = ColorCapabilities.BlueChromaticity_x; 250 pGdiInfo->ciDevice.Blue.y = ColorCapabilities.BlueChromaticity_y; 251 pGdiInfo->ciDevice.AlignmentWhite.x = ColorCapabilities.WhiteChromaticity_x; 252 pGdiInfo->ciDevice.AlignmentWhite.y = ColorCapabilities.WhiteChromaticity_y; 253 pGdiInfo->ciDevice.AlignmentWhite.Y = ColorCapabilities.WhiteChromaticity_Y; 254 if (ColorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR) 255 { 256 pGdiInfo->ciDevice.RedGamma = ColorCapabilities.RedGamma; 257 pGdiInfo->ciDevice.GreenGamma = ColorCapabilities.GreenGamma; 258 pGdiInfo->ciDevice.BlueGamma = ColorCapabilities.BlueGamma; 259 } 260 else 261 { 262 pGdiInfo->ciDevice.RedGamma = ColorCapabilities.WhiteGamma; 263 pGdiInfo->ciDevice.GreenGamma = ColorCapabilities.WhiteGamma; 264 pGdiInfo->ciDevice.BlueGamma = ColorCapabilities.WhiteGamma; 265 } 266 } 267 else 268 { 269 pGdiInfo->ciDevice.Red.x = 6700; 270 pGdiInfo->ciDevice.Red.y = 3300; 271 pGdiInfo->ciDevice.Green.x = 2100; 272 pGdiInfo->ciDevice.Green.y = 7100; 273 pGdiInfo->ciDevice.Blue.x = 1400; 274 pGdiInfo->ciDevice.Blue.y = 800; 275 pGdiInfo->ciDevice.AlignmentWhite.x = 3127; 276 pGdiInfo->ciDevice.AlignmentWhite.y = 3290; 277 pGdiInfo->ciDevice.AlignmentWhite.Y = 0; 278 pGdiInfo->ciDevice.RedGamma = 20000; 279 pGdiInfo->ciDevice.GreenGamma = 20000; 280 pGdiInfo->ciDevice.BlueGamma = 20000; 281 } 282 283 pGdiInfo->ciDevice.Red.Y = 0; 284 pGdiInfo->ciDevice.Green.Y = 0; 285 pGdiInfo->ciDevice.Blue.Y = 0; 286 pGdiInfo->ciDevice.Cyan.x = 0; 287 pGdiInfo->ciDevice.Cyan.y = 0; 288 pGdiInfo->ciDevice.Cyan.Y = 0; 289 pGdiInfo->ciDevice.Magenta.x = 0; 290 pGdiInfo->ciDevice.Magenta.y = 0; 291 pGdiInfo->ciDevice.Magenta.Y = 0; 292 pGdiInfo->ciDevice.Yellow.x = 0; 293 pGdiInfo->ciDevice.Yellow.y = 0; 294 pGdiInfo->ciDevice.Yellow.Y = 0; 295 pGdiInfo->ciDevice.MagentaInCyanDye = 0; 296 pGdiInfo->ciDevice.YellowInCyanDye = 0; 297 pGdiInfo->ciDevice.CyanInMagentaDye = 0; 298 pGdiInfo->ciDevice.YellowInMagentaDye = 0; 299 pGdiInfo->ciDevice.CyanInYellowDye = 0; 300 pGdiInfo->ciDevice.MagentaInYellowDye = 0; 301 pGdiInfo->ulDevicePelsDPI = 0; 302 pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA; 303 pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M; 304 pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS; 305 306 pDevInfo->flGraphicsCaps = 0; 307 pDevInfo->lfDefaultFont = SystemFont; 308 pDevInfo->lfAnsiVarFont = AnsiVariableFont; 309 pDevInfo->lfAnsiFixFont = AnsiFixedFont; 310 pDevInfo->cFonts = 0; 311 pDevInfo->cxDither = 0; 312 pDevInfo->cyDither = 0; 313 pDevInfo->hpalDefault = 0; 314 pDevInfo->flGraphicsCaps2 = 0; 315 316 if (ppdev->BitsPerPixel == 8) 317 { 318 pGdiInfo->ulNumColors = 20; 319 pGdiInfo->ulNumPalReg = 1 << ppdev->BitsPerPixel; 320 pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP; 321 pDevInfo->flGraphicsCaps |= GCAPS_PALMANAGED; 322 pDevInfo->iDitherFormat = BMF_8BPP; 323 /* Assuming palette is orthogonal - all colors are same size. */ 324 ppdev->PaletteShift = (UCHAR)(8 - pGdiInfo->ulDACRed); 325 } 326 else 327 { 328 pGdiInfo->ulNumColors = (ULONG)(-1); 329 pGdiInfo->ulNumPalReg = 0; 330 switch (ppdev->BitsPerPixel) 331 { 332 case 16: 333 pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP; 334 pDevInfo->iDitherFormat = BMF_16BPP; 335 break; 336 337 case 24: 338 pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP; 339 pDevInfo->iDitherFormat = BMF_24BPP; 340 break; 341 342 default: 343 pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP; 344 pDevInfo->iDitherFormat = BMF_32BPP; 345 } 346 } 347 348 EngFreeMem(ModeInfo); 349 return TRUE; 350 } 351 352 /* 353 * DrvGetModes 354 * 355 * Returns the list of available modes for the device. 356 * 357 * Status 358 * @implemented 359 */ 360 361 ULONG APIENTRY 362 DrvGetModes( 363 IN HANDLE hDriver, 364 IN ULONG cjSize, 365 OUT DEVMODEW *pdm) 366 { 367 ULONG ModeCount; 368 ULONG ModeInfoSize; 369 PVIDEO_MODE_INFORMATION ModeInfo, ModeInfoPtr; 370 ULONG OutputSize; 371 372 ModeCount = GetAvailableModes(hDriver, &ModeInfo, &ModeInfoSize); 373 if (ModeCount == 0) 374 { 375 return 0; 376 } 377 378 if (pdm == NULL) 379 { 380 EngFreeMem(ModeInfo); 381 return ModeCount * sizeof(DEVMODEW); 382 } 383 384 /* 385 * Copy the information about supported modes into the output buffer. 386 */ 387 388 OutputSize = 0; 389 ModeInfoPtr = ModeInfo; 390 391 while (ModeCount-- > 0) 392 { 393 if (ModeInfoPtr->Length == 0) 394 { 395 ModeInfoPtr = (PVIDEO_MODE_INFORMATION)(((ULONG_PTR)ModeInfoPtr) + ModeInfoSize); 396 continue; 397 } 398 399 memset(pdm, 0, sizeof(DEVMODEW)); 400 memcpy(pdm->dmDeviceName, DEVICE_NAME, sizeof(DEVICE_NAME)); 401 pdm->dmSpecVersion = 402 pdm->dmDriverVersion = DM_SPECVERSION; 403 pdm->dmSize = sizeof(DEVMODEW); 404 pdm->dmDriverExtra = 0; 405 pdm->dmBitsPerPel = ModeInfoPtr->NumberOfPlanes * ModeInfoPtr->BitsPerPlane; 406 pdm->dmPelsWidth = ModeInfoPtr->VisScreenWidth; 407 pdm->dmPelsHeight = ModeInfoPtr->VisScreenHeight; 408 pdm->dmDisplayFrequency = ModeInfoPtr->Frequency; 409 pdm->dmDisplayFlags = 0; 410 pdm->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | 411 DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS; 412 413 ModeInfoPtr = (PVIDEO_MODE_INFORMATION)(((ULONG_PTR)ModeInfoPtr) + ModeInfoSize); 414 pdm = (LPDEVMODEW)(((ULONG_PTR)pdm) + sizeof(DEVMODEW)); 415 OutputSize += sizeof(DEVMODEW); 416 } 417 418 EngFreeMem(ModeInfo); 419 return OutputSize; 420 } 421