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.
21 #include "framebufacc.h"
26 * Calls the miniport to get the list of modes supported by the kernel driver,
27 * and returns the list of modes supported by the display driver.
33 PVIDEO_MODE_INFORMATION
*ModeInfo
,
37 VIDEO_NUM_MODES Modes
;
38 PVIDEO_MODE_INFORMATION ModeInfoPtr
;
41 * Get the number of modes supported by the mini-port
44 if (EngDeviceIoControl(hDriver
, IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES
, NULL
,
45 0, &Modes
, sizeof(VIDEO_NUM_MODES
), &ulTemp
))
50 *ModeInfoSize
= Modes
.ModeInformationLength
;
53 * Allocate the buffer for the miniport to write the modes in.
56 *ModeInfo
= (PVIDEO_MODE_INFORMATION
)EngAllocMem(0, Modes
.NumModes
*
57 Modes
.ModeInformationLength
, ALLOC_TAG
);
59 if (*ModeInfo
== NULL
)
65 * Ask the miniport to fill in the available modes.
68 if (EngDeviceIoControl(hDriver
, IOCTL_VIDEO_QUERY_AVAIL_MODES
, NULL
, 0,
69 *ModeInfo
, Modes
.NumModes
* Modes
.ModeInformationLength
,
72 EngFreeMem(*ModeInfo
);
73 *ModeInfo
= (PVIDEO_MODE_INFORMATION
)NULL
;
78 * Now see which of these modes are supported by the display driver.
79 * As an internal mechanism, set the length to 0 for the modes we
83 ulTemp
= Modes
.NumModes
;
84 ModeInfoPtr
= *ModeInfo
;
87 * Mode is rejected if it is not one plane, or not graphics, or is not
88 * one of 8, 16 or 32 bits per pel.
93 /* FIXME add banked graphic mode */
94 if ((ModeInfoPtr
->NumberOfPlanes
!= 1) ||
95 !(ModeInfoPtr
->AttributeFlags
& VIDEO_MODE_GRAPHICS
) ||
96 ((ModeInfoPtr
->BitsPerPlane
!= 8) &&
97 (ModeInfoPtr
->BitsPerPlane
!= 16) &&
98 (ModeInfoPtr
->BitsPerPlane
!= 24) &&
99 (ModeInfoPtr
->BitsPerPlane
!= 32)))
101 ModeInfoPtr
->Length
= 0;
104 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)
105 (((PUCHAR
)ModeInfoPtr
) + Modes
.ModeInformationLength
);
108 return Modes
.NumModes
;
120 PVIDEO_MODE_INFORMATION ModeInfo
, ModeInfoPtr
, SelectedMode
= NULL
;
121 VIDEO_COLOR_CAPABILITIES ColorCapabilities
;
123 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"};
124 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"};
125 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"};
130 * Call miniport to get information about video modes.
133 ModeCount
= GetAvailableModes(ppdev
->hDriver
, &ModeInfo
, &ModeInfoSize
);
140 * Select the video mode depending on the info passed in pDevMode.
143 if (pDevMode
->dmPelsWidth
== 0 && pDevMode
->dmPelsHeight
== 0 &&
144 pDevMode
->dmBitsPerPel
== 0 && pDevMode
->dmDisplayFrequency
== 0)
146 ModeInfoPtr
= ModeInfo
;
147 while (ModeCount
-- > 0)
149 if (ModeInfoPtr
->Length
== 0)
151 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)
152 (((PUCHAR
)ModeInfoPtr
) + ModeInfoSize
);
155 SelectedMode
= ModeInfoPtr
;
161 ModeInfoPtr
= ModeInfo
;
162 while (ModeCount
-- > 0)
164 if (ModeInfoPtr
->Length
> 0 &&
165 pDevMode
->dmPelsWidth
== ModeInfoPtr
->VisScreenWidth
&&
166 pDevMode
->dmPelsHeight
== ModeInfoPtr
->VisScreenHeight
&&
167 pDevMode
->dmBitsPerPel
== (ModeInfoPtr
->BitsPerPlane
*
168 ModeInfoPtr
->NumberOfPlanes
) &&
169 pDevMode
->dmDisplayFrequency
== ModeInfoPtr
->Frequency
)
171 SelectedMode
= ModeInfoPtr
;
175 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)
176 (((PUCHAR
)ModeInfoPtr
) + ModeInfoSize
);
180 if (SelectedMode
== NULL
)
182 EngFreeMem(ModeInfo
);
187 * Fill in the GDIINFO data structure with the information returned from
191 ppdev
->ModeIndex
= SelectedMode
->ModeIndex
;
192 ppdev
->ScreenWidth
= SelectedMode
->VisScreenWidth
;
193 ppdev
->ScreenHeight
= SelectedMode
->VisScreenHeight
;
194 ppdev
->ScreenDelta
= SelectedMode
->ScreenStride
;
195 ppdev
->BitsPerPixel
= SelectedMode
->BitsPerPlane
* SelectedMode
->NumberOfPlanes
;
197 ppdev
->MemWidth
= SelectedMode
->VideoMemoryBitmapWidth
;
198 ppdev
->MemHeight
= SelectedMode
->VideoMemoryBitmapHeight
;
200 ppdev
->RedMask
= SelectedMode
->RedMask
;
201 ppdev
->GreenMask
= SelectedMode
->GreenMask
;
202 ppdev
->BlueMask
= SelectedMode
->BlueMask
;
204 pGdiInfo
->ulVersion
= GDI_DRIVER_VERSION
;
205 pGdiInfo
->ulTechnology
= DT_RASDISPLAY
;
206 pGdiInfo
->ulHorzSize
= SelectedMode
->XMillimeter
;
207 pGdiInfo
->ulVertSize
= SelectedMode
->YMillimeter
;
208 pGdiInfo
->ulHorzRes
= SelectedMode
->VisScreenWidth
;
209 pGdiInfo
->ulVertRes
= SelectedMode
->VisScreenHeight
;
210 pGdiInfo
->ulPanningHorzRes
= SelectedMode
->VisScreenWidth
;
211 pGdiInfo
->ulPanningVertRes
= SelectedMode
->VisScreenHeight
;
212 pGdiInfo
->cBitsPixel
= SelectedMode
->BitsPerPlane
;
213 pGdiInfo
->cPlanes
= SelectedMode
->NumberOfPlanes
;
214 pGdiInfo
->ulVRefresh
= SelectedMode
->Frequency
;
215 pGdiInfo
->ulBltAlignment
= 1;
216 pGdiInfo
->ulLogPixelsX
= pDevMode
->dmLogPixels
;
217 pGdiInfo
->ulLogPixelsY
= pDevMode
->dmLogPixels
;
218 pGdiInfo
->flTextCaps
= TC_RA_ABLE
;
219 pGdiInfo
->flRaster
= 0;
220 pGdiInfo
->ulDACRed
= SelectedMode
->NumberRedBits
;
221 pGdiInfo
->ulDACGreen
= SelectedMode
->NumberGreenBits
;
222 pGdiInfo
->ulDACBlue
= SelectedMode
->NumberBlueBits
;
223 pGdiInfo
->ulAspectX
= 0x24;
224 pGdiInfo
->ulAspectY
= 0x24;
225 pGdiInfo
->ulAspectXY
= 0x33;
226 pGdiInfo
->xStyleStep
= 1;
227 pGdiInfo
->yStyleStep
= 1;
228 pGdiInfo
->denStyleStep
= 3;
229 pGdiInfo
->ptlPhysOffset
.x
= 0;
230 pGdiInfo
->ptlPhysOffset
.y
= 0;
231 pGdiInfo
->szlPhysSize
.cx
= 0;
232 pGdiInfo
->szlPhysSize
.cy
= 0;
235 * Try to get the color info from the miniport.
238 if (!EngDeviceIoControl(ppdev
->hDriver
, IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES
,
239 NULL
, 0, &ColorCapabilities
,
240 sizeof(VIDEO_COLOR_CAPABILITIES
), &Temp
))
242 pGdiInfo
->ciDevice
.Red
.x
= ColorCapabilities
.RedChromaticity_x
;
243 pGdiInfo
->ciDevice
.Red
.y
= ColorCapabilities
.RedChromaticity_y
;
244 pGdiInfo
->ciDevice
.Green
.x
= ColorCapabilities
.GreenChromaticity_x
;
245 pGdiInfo
->ciDevice
.Green
.y
= ColorCapabilities
.GreenChromaticity_y
;
246 pGdiInfo
->ciDevice
.Blue
.x
= ColorCapabilities
.BlueChromaticity_x
;
247 pGdiInfo
->ciDevice
.Blue
.y
= ColorCapabilities
.BlueChromaticity_y
;
248 pGdiInfo
->ciDevice
.AlignmentWhite
.x
= ColorCapabilities
.WhiteChromaticity_x
;
249 pGdiInfo
->ciDevice
.AlignmentWhite
.y
= ColorCapabilities
.WhiteChromaticity_y
;
250 pGdiInfo
->ciDevice
.AlignmentWhite
.Y
= ColorCapabilities
.WhiteChromaticity_Y
;
251 if (ColorCapabilities
.AttributeFlags
& VIDEO_DEVICE_COLOR
)
253 pGdiInfo
->ciDevice
.RedGamma
= ColorCapabilities
.RedGamma
;
254 pGdiInfo
->ciDevice
.GreenGamma
= ColorCapabilities
.GreenGamma
;
255 pGdiInfo
->ciDevice
.BlueGamma
= ColorCapabilities
.BlueGamma
;
259 pGdiInfo
->ciDevice
.RedGamma
= ColorCapabilities
.WhiteGamma
;
260 pGdiInfo
->ciDevice
.GreenGamma
= ColorCapabilities
.WhiteGamma
;
261 pGdiInfo
->ciDevice
.BlueGamma
= ColorCapabilities
.WhiteGamma
;
266 pGdiInfo
->ciDevice
.Red
.x
= 6700;
267 pGdiInfo
->ciDevice
.Red
.y
= 3300;
268 pGdiInfo
->ciDevice
.Green
.x
= 2100;
269 pGdiInfo
->ciDevice
.Green
.y
= 7100;
270 pGdiInfo
->ciDevice
.Blue
.x
= 1400;
271 pGdiInfo
->ciDevice
.Blue
.y
= 800;
272 pGdiInfo
->ciDevice
.AlignmentWhite
.x
= 3127;
273 pGdiInfo
->ciDevice
.AlignmentWhite
.y
= 3290;
274 pGdiInfo
->ciDevice
.AlignmentWhite
.Y
= 0;
275 pGdiInfo
->ciDevice
.RedGamma
= 20000;
276 pGdiInfo
->ciDevice
.GreenGamma
= 20000;
277 pGdiInfo
->ciDevice
.BlueGamma
= 20000;
280 pGdiInfo
->ciDevice
.Red
.Y
= 0;
281 pGdiInfo
->ciDevice
.Green
.Y
= 0;
282 pGdiInfo
->ciDevice
.Blue
.Y
= 0;
283 pGdiInfo
->ciDevice
.Cyan
.x
= 0;
284 pGdiInfo
->ciDevice
.Cyan
.y
= 0;
285 pGdiInfo
->ciDevice
.Cyan
.Y
= 0;
286 pGdiInfo
->ciDevice
.Magenta
.x
= 0;
287 pGdiInfo
->ciDevice
.Magenta
.y
= 0;
288 pGdiInfo
->ciDevice
.Magenta
.Y
= 0;
289 pGdiInfo
->ciDevice
.Yellow
.x
= 0;
290 pGdiInfo
->ciDevice
.Yellow
.y
= 0;
291 pGdiInfo
->ciDevice
.Yellow
.Y
= 0;
292 pGdiInfo
->ciDevice
.MagentaInCyanDye
= 0;
293 pGdiInfo
->ciDevice
.YellowInCyanDye
= 0;
294 pGdiInfo
->ciDevice
.CyanInMagentaDye
= 0;
295 pGdiInfo
->ciDevice
.YellowInMagentaDye
= 0;
296 pGdiInfo
->ciDevice
.CyanInYellowDye
= 0;
297 pGdiInfo
->ciDevice
.MagentaInYellowDye
= 0;
298 pGdiInfo
->ulDevicePelsDPI
= 0;
299 pGdiInfo
->ulPrimaryOrder
= PRIMARY_ORDER_CBA
;
300 pGdiInfo
->ulHTPatternSize
= HT_PATSIZE_4x4_M
;
301 pGdiInfo
->flHTFlags
= HT_FLAG_ADDITIVE_PRIMS
;
303 pDevInfo
->flGraphicsCaps
= 0;
305 pDevInfo->lfDefaultFont = SystemFont;
306 pDevInfo->lfAnsiVarFont = AnsiVariableFont;
307 pDevInfo->lfAnsiFixFont = AnsiFixedFont;
309 pDevInfo
->cFonts
= 0;
310 pDevInfo
->cxDither
= 0;
311 pDevInfo
->cyDither
= 0;
312 pDevInfo
->hpalDefault
= 0;
313 pDevInfo
->flGraphicsCaps2
= 0;
315 if (ppdev
->BitsPerPixel
== 8)
317 pGdiInfo
->ulNumColors
= 20;
318 pGdiInfo
->ulNumPalReg
= 1 << ppdev
->BitsPerPixel
;
319 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_8BPP
;
320 pDevInfo
->flGraphicsCaps
|= GCAPS_PALMANAGED
;
321 pDevInfo
->iDitherFormat
= BMF_8BPP
;
322 /* Assuming palette is orthogonal - all colors are same size. */
323 ppdev
->PaletteShift
= 8 - pGdiInfo
->ulDACRed
;
327 pGdiInfo
->ulNumColors
= (ULONG
)(-1);
328 pGdiInfo
->ulNumPalReg
= 0;
329 switch (ppdev
->BitsPerPixel
)
332 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_16BPP
;
333 pDevInfo
->iDitherFormat
= BMF_16BPP
;
337 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_24BPP
;
338 pDevInfo
->iDitherFormat
= BMF_24BPP
;
342 pGdiInfo
->ulHTOutputFormat
= HT_FORMAT_32BPP
;
343 pDevInfo
->iDitherFormat
= BMF_32BPP
;
347 EngFreeMem(ModeInfo
);
354 * Returns the list of available modes for the device.
368 PVIDEO_MODE_INFORMATION ModeInfo
, ModeInfoPtr
;
371 ModeCount
= GetAvailableModes(hDriver
, &ModeInfo
, &ModeInfoSize
);
379 EngFreeMem(ModeInfo
);
380 return ModeCount
* sizeof(DEVMODEW
);
384 * Copy the information about supported modes into the output buffer.
388 ModeInfoPtr
= ModeInfo
;
390 while (ModeCount
-- > 0)
392 if (ModeInfoPtr
->Length
== 0)
394 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)(((ULONG_PTR
)ModeInfoPtr
) + ModeInfoSize
);
398 memset(pdm
, 0, sizeof(DEVMODEW
));
399 memcpy(pdm
->dmDeviceName
, DEVICE_NAME
, sizeof(DEVICE_NAME
));
401 pdm
->dmDriverVersion
= DM_SPECVERSION
;
402 pdm
->dmSize
= sizeof(DEVMODEW
);
403 pdm
->dmDriverExtra
= 0;
404 pdm
->dmBitsPerPel
= ModeInfoPtr
->NumberOfPlanes
* ModeInfoPtr
->BitsPerPlane
;
405 pdm
->dmPelsWidth
= ModeInfoPtr
->VisScreenWidth
;
406 pdm
->dmPelsHeight
= ModeInfoPtr
->VisScreenHeight
;
407 pdm
->dmDisplayFrequency
= ModeInfoPtr
->Frequency
;
408 pdm
->dmDisplayFlags
= 0;
409 pdm
->dmFields
= DM_BITSPERPEL
| DM_PELSWIDTH
| DM_PELSHEIGHT
|
410 DM_DISPLAYFREQUENCY
| DM_DISPLAYFLAGS
;
412 ModeInfoPtr
= (PVIDEO_MODE_INFORMATION
)(((ULONG_PTR
)ModeInfoPtr
) + ModeInfoSize
);
413 pdm
= (LPDEVMODEW
)(((ULONG_PTR
)pdm
) + sizeof(DEVMODEW
));
414 OutputSize
+= sizeof(DEVMODEW
);
417 EngFreeMem(ModeInfo
);