2 * ReactOS Generic Framebuffer display driver
4 * Copyright (C) 2004 Filip Navara
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.
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.
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.
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" };
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.
37 PVIDEO_MODE_INFORMATION
*ModeInfo
,
41 VIDEO_NUM_MODES Modes
;
42 PVIDEO_MODE_INFORMATION ModeInfoPtr
;
45 * Get the number of modes supported by the mini-port
48 if (EngDeviceIoControl(hDriver
, IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
, NULL
,
49 0, &Modes
, sizeof(VIDEO_NUM_MODES
), &ulTemp
))
54 *ModeInfoSize
= Modes
.ModeInformationLength
;
57 * Allocate the buffer for the miniport to write the modes in.
60 *ModeInfo
= (PVIDEO_MODE_INFORMATION
)EngAllocMem(0, Modes
.NumModes
*
61 Modes
.ModeInformationLength
, ALLOC_TAG
);
63 if (*ModeInfo
== NULL
)
69 * Ask the miniport to fill in the available modes.
72 if (EngDeviceIoControl(hDriver
, IOCTL_VIDEO_QUERY_AVAIL_MODES
, NULL
, 0,
73 *ModeInfo
, Modes
.NumModes
* Modes
.ModeInformationLength
,
76 EngFreeMem(*ModeInfo
);
77 *ModeInfo
= (PVIDEO_MODE_INFORMATION
)NULL
;
82 * Now see which of these modes are supported by the display driver.
83 * As an internal mechanism, set the length to 0 for the modes we
87 ulTemp
= Modes
.NumModes
;
88 ModeInfoPtr
= *ModeInfo
;
91 * Mode is rejected if it is not one plane, or not graphics, or is not
92 * one of 8, 16 or 32 bits per pel.
97 if ((ModeInfoPtr
->NumberOfPlanes
!= 1) ||
98 !(ModeInfoPtr
->AttributeFlags
& VIDEO_MODE_GRAPHICS
) ||
99 ((ModeInfoPtr
->BitsPerPlane
!= 8) &&
100 (ModeInfoPtr
->BitsPerPlane
!= 16) &&
101 (ModeInfoPtr
->BitsPerPlane
!= 24) &&
102 (ModeInfoPtr
->BitsPerPlane
!= 32)))
104 ModeInfoPtr
->Length
= 0;
107 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)
108 (((PUCHAR
)ModeInfoPtr
) + Modes
.ModeInformationLength
);
111 return Modes
.NumModes
;
123 PVIDEO_MODE_INFORMATION ModeInfo
, ModeInfoPtr
, SelectedMode
= NULL
;
124 VIDEO_COLOR_CAPABILITIES ColorCapabilities
;
128 * Call miniport to get information about video modes.
131 ModeCount
= GetAvailableModes(ppdev
->hDriver
, &ModeInfo
, &ModeInfoSize
);
138 * Select the video mode depending on the info passed in pDevMode.
141 if (pDevMode
->dmPelsWidth
== 0 && pDevMode
->dmPelsHeight
== 0 &&
142 pDevMode
->dmBitsPerPel
== 0 && pDevMode
->dmDisplayFrequency
== 0)
144 ModeInfoPtr
= ModeInfo
;
145 while (ModeCount
-- > 0)
147 if (ModeInfoPtr
->Length
== 0)
149 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)
150 (((PUCHAR
)ModeInfoPtr
) + ModeInfoSize
);
153 SelectedMode
= ModeInfoPtr
;
159 ModeInfoPtr
= ModeInfo
;
160 while (ModeCount
-- > 0)
162 if (ModeInfoPtr
->Length
> 0 &&
163 pDevMode
->dmPelsWidth
== ModeInfoPtr
->VisScreenWidth
&&
164 pDevMode
->dmPelsHeight
== ModeInfoPtr
->VisScreenHeight
&&
165 pDevMode
->dmBitsPerPel
== (ModeInfoPtr
->BitsPerPlane
*
166 ModeInfoPtr
->NumberOfPlanes
) &&
167 pDevMode
->dmDisplayFrequency
== ModeInfoPtr
->Frequency
)
169 SelectedMode
= ModeInfoPtr
;
173 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)
174 (((PUCHAR
)ModeInfoPtr
) + ModeInfoSize
);
178 if (SelectedMode
== NULL
)
180 EngFreeMem(ModeInfo
);
185 * Fill in the GDIINFO data structure with the information returned from
189 ppdev
->ModeIndex
= SelectedMode
->ModeIndex
;
190 ppdev
->ScreenWidth
= SelectedMode
->VisScreenWidth
;
191 ppdev
->ScreenHeight
= SelectedMode
->VisScreenHeight
;
192 ppdev
->ScreenDelta
= SelectedMode
->ScreenStride
;
193 ppdev
->BitsPerPixel
= SelectedMode
->BitsPerPlane
* SelectedMode
->NumberOfPlanes
;
195 ppdev
->MemWidth
= SelectedMode
->VideoMemoryBitmapWidth
;
196 ppdev
->MemHeight
= SelectedMode
->VideoMemoryBitmapHeight
;
198 ppdev
->RedMask
= SelectedMode
->RedMask
;
199 ppdev
->GreenMask
= SelectedMode
->GreenMask
;
200 ppdev
->BlueMask
= SelectedMode
->BlueMask
;
202 pGdiInfo
->ulVersion
= GDI_DRIVER_VERSION
;
203 pGdiInfo
->ulTechnology
= DT_RASDISPLAY
;
204 pGdiInfo
->ulHorzSize
= SelectedMode
->XMillimeter
;
205 pGdiInfo
->ulVertSize
= SelectedMode
->YMillimeter
;
206 pGdiInfo
->ulHorzRes
= SelectedMode
->VisScreenWidth
;
207 pGdiInfo
->ulVertRes
= SelectedMode
->VisScreenHeight
;
208 pGdiInfo
->ulPanningHorzRes
= SelectedMode
->VisScreenWidth
;
209 pGdiInfo
->ulPanningVertRes
= SelectedMode
->VisScreenHeight
;
210 pGdiInfo
->cBitsPixel
= SelectedMode
->BitsPerPlane
;
211 pGdiInfo
->cPlanes
= SelectedMode
->NumberOfPlanes
;
212 pGdiInfo
->ulVRefresh
= SelectedMode
->Frequency
;
213 pGdiInfo
->ulBltAlignment
= 1;
214 pGdiInfo
->ulLogPixelsX
= pDevMode
->dmLogPixels
;
215 pGdiInfo
->ulLogPixelsY
= pDevMode
->dmLogPixels
;
216 pGdiInfo
->flTextCaps
= TC_RA_ABLE
;
217 pGdiInfo
->flRaster
= 0;
218 pGdiInfo
->ulDACRed
= SelectedMode
->NumberRedBits
;
219 pGdiInfo
->ulDACGreen
= SelectedMode
->NumberGreenBits
;
220 pGdiInfo
->ulDACBlue
= SelectedMode
->NumberBlueBits
;
221 pGdiInfo
->ulAspectX
= 0x24;
222 pGdiInfo
->ulAspectY
= 0x24;
223 pGdiInfo
->ulAspectXY
= 0x33;
224 pGdiInfo
->xStyleStep
= 1;
225 pGdiInfo
->yStyleStep
= 1;
226 pGdiInfo
->denStyleStep
= 3;
227 pGdiInfo
->ptlPhysOffset
.x
= 0;
228 pGdiInfo
->ptlPhysOffset
.y
= 0;
229 pGdiInfo
->szlPhysSize
.cx
= 0;
230 pGdiInfo
->szlPhysSize
.cy
= 0;
233 * Try to get the color info from the miniport.
236 if (!EngDeviceIoControl(ppdev
->hDriver
, IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES
,
237 NULL
, 0, &ColorCapabilities
,
238 sizeof(VIDEO_COLOR_CAPABILITIES
), &Temp
))
240 pGdiInfo
->ciDevice
.Red
.x
= ColorCapabilities
.RedChromaticity_x
;
241 pGdiInfo
->ciDevice
.Red
.y
= ColorCapabilities
.RedChromaticity_y
;
242 pGdiInfo
->ciDevice
.Green
.x
= ColorCapabilities
.GreenChromaticity_x
;
243 pGdiInfo
->ciDevice
.Green
.y
= ColorCapabilities
.GreenChromaticity_y
;
244 pGdiInfo
->ciDevice
.Blue
.x
= ColorCapabilities
.BlueChromaticity_x
;
245 pGdiInfo
->ciDevice
.Blue
.y
= ColorCapabilities
.BlueChromaticity_y
;
246 pGdiInfo
->ciDevice
.AlignmentWhite
.x
= ColorCapabilities
.WhiteChromaticity_x
;
247 pGdiInfo
->ciDevice
.AlignmentWhite
.y
= ColorCapabilities
.WhiteChromaticity_y
;
248 pGdiInfo
->ciDevice
.AlignmentWhite
.Y
= ColorCapabilities
.WhiteChromaticity_Y
;
249 if (ColorCapabilities
.AttributeFlags
& VIDEO_DEVICE_COLOR
)
251 pGdiInfo
->ciDevice
.RedGamma
= ColorCapabilities
.RedGamma
;
252 pGdiInfo
->ciDevice
.GreenGamma
= ColorCapabilities
.GreenGamma
;
253 pGdiInfo
->ciDevice
.BlueGamma
= ColorCapabilities
.BlueGamma
;
257 pGdiInfo
->ciDevice
.RedGamma
= ColorCapabilities
.WhiteGamma
;
258 pGdiInfo
->ciDevice
.GreenGamma
= ColorCapabilities
.WhiteGamma
;
259 pGdiInfo
->ciDevice
.BlueGamma
= ColorCapabilities
.WhiteGamma
;
264 pGdiInfo
->ciDevice
.Red
.x
= 6700;
265 pGdiInfo
->ciDevice
.Red
.y
= 3300;
266 pGdiInfo
->ciDevice
.Green
.x
= 2100;
267 pGdiInfo
->ciDevice
.Green
.y
= 7100;
268 pGdiInfo
->ciDevice
.Blue
.x
= 1400;
269 pGdiInfo
->ciDevice
.Blue
.y
= 800;
270 pGdiInfo
->ciDevice
.AlignmentWhite
.x
= 3127;
271 pGdiInfo
->ciDevice
.AlignmentWhite
.y
= 3290;
272 pGdiInfo
->ciDevice
.AlignmentWhite
.Y
= 0;
273 pGdiInfo
->ciDevice
.RedGamma
= 20000;
274 pGdiInfo
->ciDevice
.GreenGamma
= 20000;
275 pGdiInfo
->ciDevice
.BlueGamma
= 20000;
278 pGdiInfo
->ciDevice
.Red
.Y
= 0;
279 pGdiInfo
->ciDevice
.Green
.Y
= 0;
280 pGdiInfo
->ciDevice
.Blue
.Y
= 0;
281 pGdiInfo
->ciDevice
.Cyan
.x
= 0;
282 pGdiInfo
->ciDevice
.Cyan
.y
= 0;
283 pGdiInfo
->ciDevice
.Cyan
.Y
= 0;
284 pGdiInfo
->ciDevice
.Magenta
.x
= 0;
285 pGdiInfo
->ciDevice
.Magenta
.y
= 0;
286 pGdiInfo
->ciDevice
.Magenta
.Y
= 0;
287 pGdiInfo
->ciDevice
.Yellow
.x
= 0;
288 pGdiInfo
->ciDevice
.Yellow
.y
= 0;
289 pGdiInfo
->ciDevice
.Yellow
.Y
= 0;
290 pGdiInfo
->ciDevice
.MagentaInCyanDye
= 0;
291 pGdiInfo
->ciDevice
.YellowInCyanDye
= 0;
292 pGdiInfo
->ciDevice
.CyanInMagentaDye
= 0;
293 pGdiInfo
->ciDevice
.YellowInMagentaDye
= 0;
294 pGdiInfo
->ciDevice
.CyanInYellowDye
= 0;
295 pGdiInfo
->ciDevice
.MagentaInYellowDye
= 0;
296 pGdiInfo
->ulDevicePelsDPI
= 0;
297 pGdiInfo
->ulPrimaryOrder
= PRIMARY_ORDER_CBA
;
298 pGdiInfo
->ulHTPatternSize
= HT_PATSIZE_4x4_M
;
299 pGdiInfo
->flHTFlags
= HT_FLAG_ADDITIVE_PRIMS
;
301 pDevInfo
->flGraphicsCaps
= 0;
302 pDevInfo
->lfDefaultFont
= SystemFont
;
303 pDevInfo
->lfAnsiVarFont
= AnsiVariableFont
;
304 pDevInfo
->lfAnsiFixFont
= AnsiFixedFont
;
305 pDevInfo
->cFonts
= 0;
306 pDevInfo
->cxDither
= 0;
307 pDevInfo
->cyDither
= 0;
308 pDevInfo
->hpalDefault
= 0;
309 pDevInfo
->flGraphicsCaps2
= 0;
311 if (ppdev
->BitsPerPixel
== 8)
313 pGdiInfo
->ulNumColors
= 20;
314 pGdiInfo
->ulNumPalReg
= 1 << ppdev
->BitsPerPixel
;
315 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_8BPP
;
316 pDevInfo
->flGraphicsCaps
|= GCAPS_PALMANAGED
;
317 pDevInfo
->iDitherFormat
= BMF_8BPP
;
318 /* Assuming palette is orthogonal - all colors are same size. */
319 ppdev
->PaletteShift
= 8 - pGdiInfo
->ulDACRed
;
323 pGdiInfo
->ulNumColors
= (ULONG
)(-1);
324 pGdiInfo
->ulNumPalReg
= 0;
325 switch (ppdev
->BitsPerPixel
)
328 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_16BPP
;
329 pDevInfo
->iDitherFormat
= BMF_16BPP
;
333 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_24BPP
;
334 pDevInfo
->iDitherFormat
= BMF_24BPP
;
338 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_32BPP
;
339 pDevInfo
->iDitherFormat
= BMF_32BPP
;
343 EngFreeMem(ModeInfo
);
350 * Returns the list of available modes for the device.
364 PVIDEO_MODE_INFORMATION ModeInfo
, ModeInfoPtr
;
367 ModeCount
= GetAvailableModes(hDriver
, &ModeInfo
, &ModeInfoSize
);
375 EngFreeMem(ModeInfo
);
376 return ModeCount
* sizeof(DEVMODEW
);
380 * Copy the information about supported modes into the output buffer.
384 ModeInfoPtr
= ModeInfo
;
386 while (ModeCount
-- > 0)
388 if (ModeInfoPtr
->Length
== 0)
390 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)(((ULONG_PTR
)ModeInfoPtr
) + ModeInfoSize
);
394 memset(pdm
, 0, sizeof(DEVMODEW
));
395 memcpy(pdm
->dmDeviceName
, DEVICE_NAME
, sizeof(DEVICE_NAME
));
397 pdm
->dmDriverVersion
= DM_SPECVERSION
;
398 pdm
->dmSize
= sizeof(DEVMODEW
);
399 pdm
->dmDriverExtra
= 0;
400 pdm
->dmBitsPerPel
= ModeInfoPtr
->NumberOfPlanes
* ModeInfoPtr
->BitsPerPlane
;
401 pdm
->dmPelsWidth
= ModeInfoPtr
->VisScreenWidth
;
402 pdm
->dmPelsHeight
= ModeInfoPtr
->VisScreenHeight
;
403 pdm
->dmDisplayFrequency
= ModeInfoPtr
->Frequency
;
404 pdm
->dmDisplayFlags
= 0;
405 pdm
->dmFields
= DM_BITSPERPEL
| DM_PELSWIDTH
| DM_PELSHEIGHT
|
406 DM_DISPLAYFREQUENCY
| DM_DISPLAYFLAGS
;
408 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)(((ULONG_PTR
)ModeInfoPtr
) + ModeInfoSize
);
409 pdm
= (LPDEVMODEW
)(((ULONG_PTR
)pdm
) + sizeof(DEVMODEW
));
410 OutputSize
+= sizeof(DEVMODEW
);
413 EngFreeMem(ModeInfo
);