mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
286 lines
7.3 KiB
C
286 lines
7.3 KiB
C
|
|
|
|
/* SDK/DDK/NDK Headers. */
|
|
#define WIN32_NO_STATUS
|
|
#include <windef.h>
|
|
#include <winbase.h>
|
|
#include <wingdi.h>
|
|
#include <winddi.h>
|
|
#include <winuser.h>
|
|
#include <prntfont.h>
|
|
|
|
#define NTOS_MODE_USER
|
|
#include <ndk/ntndk.h>
|
|
|
|
/* Public Win32K Headers */
|
|
#include <ntgdityp.h>
|
|
#include <ntgdi.h>
|
|
#include <ntgdihdl.h>
|
|
|
|
#include "gditools.h"
|
|
|
|
HBITMAP ghbmp1, ghbmp1_InvCol, ghbmp1_RB, ghbmp4, ghbmp8, ghbmp16, ghbmp24, ghbmp32;
|
|
HBITMAP ghbmpDIB1, ghbmpDIB1_InvCol, ghbmpDIB1_RB, ghbmpDIB4, ghbmpDIB8, ghbmpDIB16, ghbmpDIB24, ghbmpDIB32;
|
|
HDC ghdcDIB1, ghdcDIB1_InvCol, ghdcDIB1_RB, ghdcDIB4, ghdcDIB8, ghdcDIB16, ghdcDIB24, ghdcDIB32;
|
|
PVOID gpvDIB1, gpvDIB1_InvCol, gpvDIB1_RB, gpvDIB4, gpvDIB8, gpvDIB16, gpvDIB24, gpvDIB32;
|
|
ULONG (*gpDIB32)[8][8];
|
|
HPALETTE ghpal;
|
|
HDC ghdcInfo;
|
|
|
|
MYPAL gpal =
|
|
{
|
|
0x300, 8,
|
|
{
|
|
{ 0x10, 0x20, 0x30, PC_NOCOLLAPSE },
|
|
{ 0x20, 0x30, 0x40, PC_NOCOLLAPSE },
|
|
{ 0x30, 0x40, 0x50, PC_NOCOLLAPSE },
|
|
{ 0x40, 0x50, 0x60, PC_NOCOLLAPSE },
|
|
{ 0x50, 0x60, 0x70, PC_NOCOLLAPSE },
|
|
{ 0x60, 0x70, 0x80, PC_NOCOLLAPSE },
|
|
{ 0x70, 0x80, 0x90, PC_NOCOLLAPSE },
|
|
{ 0x80, 0x90, 0xA0, PC_NOCOLLAPSE },
|
|
}
|
|
};
|
|
|
|
PENTRY
|
|
GdiQueryTable(
|
|
VOID)
|
|
{
|
|
PTEB pTeb = NtCurrentTeb();
|
|
PPEB pPeb = pTeb->ProcessEnvironmentBlock;
|
|
return pPeb->GdiSharedHandleTable;
|
|
}
|
|
|
|
BOOL
|
|
GdiIsHandleValid(
|
|
_In_ HGDIOBJ hobj)
|
|
{
|
|
PENTRY pentHmgr = GdiQueryTable();
|
|
USHORT Index = (ULONG_PTR)hobj & 0xFFFF;
|
|
PENTRY pentry = &pentHmgr[Index];
|
|
|
|
if ((pentry->einfo.pobj == NULL) ||
|
|
((LONG_PTR)pentry->einfo.pobj > 0) ||
|
|
(pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
GdiIsHandleValidEx(
|
|
_In_ HGDIOBJ hobj,
|
|
_In_ GDILOOBJTYPE ObjectType)
|
|
{
|
|
PENTRY pentHmgr = GdiQueryTable();
|
|
USHORT Index = (ULONG_PTR)hobj & 0xFFFF;
|
|
PENTRY pentry = &pentHmgr[Index];
|
|
|
|
if ((pentry->einfo.pobj == NULL) ||
|
|
((LONG_PTR)pentry->einfo.pobj > 0) ||
|
|
(pentry->FullUnique != (USHORT)((ULONG_PTR)hobj >> 16)) ||
|
|
(pentry->Objt != (UCHAR)(ObjectType >> 16)) ||
|
|
(pentry->Flags != (UCHAR)(ObjectType >> 24)))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
PVOID
|
|
GdiGetHandleUserData(
|
|
_In_ HGDIOBJ hobj)
|
|
{
|
|
PENTRY pentHmgr = GdiQueryTable();
|
|
USHORT Index = (ULONG_PTR)hobj;
|
|
PENTRY pentry = &pentHmgr[Index];
|
|
|
|
if (!GdiIsHandleValid(hobj))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return pentry->pUser;
|
|
}
|
|
|
|
VOID
|
|
PrintAvailableDisplayModes(void)
|
|
{
|
|
DEVMODEW dm = { .dmSize = sizeof(dm) };
|
|
ULONG iMode = 0;
|
|
|
|
printf("Available display modes:\n");
|
|
while (EnumDisplaySettingsW(NULL, iMode++, &dm))
|
|
{
|
|
printf(" %ux%u @ %u bpp, freq: %u Hz\n",
|
|
dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency);
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
ChangeScreenBpp(
|
|
_In_ ULONG cBitsPixel,
|
|
_Out_ PDEVMODEW pdmOld)
|
|
{
|
|
DEVMODEW dm = { .dmSize = sizeof(dm) };
|
|
|
|
if (!EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dm))
|
|
{
|
|
printf("EnumDisplaySettingsW failed\n");
|
|
return FALSE;
|
|
}
|
|
|
|
printf("ChangeScreenBpp(%lu): Old display settings: %ux%u @ %u bpp\n",
|
|
cBitsPixel, dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel);
|
|
|
|
*pdmOld = dm;
|
|
|
|
if (dm.dmBitsPerPel != cBitsPixel)
|
|
{
|
|
dm.dmBitsPerPel = cBitsPixel;
|
|
if (ChangeDisplaySettingsW(&dm, 0) != DISP_CHANGE_SUCCESSFUL)
|
|
{
|
|
printf("Failed to change display settings.\n");
|
|
PrintAvailableDisplayModes();
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dm);
|
|
printf("ChangeScreenBpp(%lu): New display settings: %ux%u @ %u bpp\n",
|
|
cBitsPixel, dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#define FL_INVERT_COLORS 0x01
|
|
#define FL_RED_BLUE 0x02
|
|
|
|
static
|
|
BOOL
|
|
InitPerBitDepth(
|
|
_In_ ULONG cBitsPerPixel,
|
|
_In_ ULONG cx,
|
|
_In_ ULONG cy,
|
|
_Out_opt_ HBITMAP *phbmpDDB,
|
|
_Out_ HDC *phdcDIB,
|
|
_Out_ HBITMAP *phbmpDIB,
|
|
_Out_ PVOID *ppvBits,
|
|
_In_ ULONG flags)
|
|
{
|
|
struct
|
|
{
|
|
BITMAPINFOHEADER bmiHeader;
|
|
ULONG bmiColors[256];
|
|
} bmiBuffer;
|
|
LPBITMAPINFO pbmi = (LPBITMAPINFO)&bmiBuffer;
|
|
|
|
if (phbmpDDB != NULL)
|
|
{
|
|
/* Create a bitmap */
|
|
*phbmpDDB = CreateBitmap(cx, cy, 1, cBitsPerPixel, NULL);
|
|
if (*phbmpDDB == NULL)
|
|
{
|
|
printf("CreateBitmap failed %lu\n", cBitsPerPixel);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/* Setup bitmap info */
|
|
memset(&bmiBuffer, 0, sizeof(bmiBuffer));
|
|
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
pbmi->bmiHeader.biWidth = cx;
|
|
pbmi->bmiHeader.biHeight = -(LONG)cy;
|
|
pbmi->bmiHeader.biPlanes = 1;
|
|
pbmi->bmiHeader.biBitCount = cBitsPerPixel;
|
|
pbmi->bmiHeader.biCompression = BI_RGB;
|
|
pbmi->bmiHeader.biSizeImage = 0;
|
|
pbmi->bmiHeader.biXPelsPerMeter = 0;
|
|
pbmi->bmiHeader.biYPelsPerMeter = 0;
|
|
pbmi->bmiHeader.biClrUsed = 0;
|
|
pbmi->bmiHeader.biClrImportant = 0;
|
|
|
|
if (cBitsPerPixel == 1)
|
|
{
|
|
if (flags & FL_RED_BLUE)
|
|
{
|
|
bmiBuffer.bmiColors[0] = RGB(0xFF, 0x00, 0x00);
|
|
bmiBuffer.bmiColors[1] = RGB(0x00, 0x00, 0xFF);
|
|
}
|
|
else if (flags & FL_INVERT_COLORS)
|
|
{
|
|
bmiBuffer.bmiColors[0] = 0xFFFFFF;
|
|
bmiBuffer.bmiColors[1] = 0;
|
|
}
|
|
else
|
|
{
|
|
bmiBuffer.bmiColors[0] = 0;
|
|
bmiBuffer.bmiColors[1] = 0xFFFFFF;
|
|
}
|
|
pbmi->bmiHeader.biClrUsed = 2;
|
|
}
|
|
|
|
/* Create a compatible DC for the DIB */
|
|
*phdcDIB = CreateCompatibleDC(0);
|
|
if (*phdcDIB == NULL)
|
|
{
|
|
printf("CreateCompatibleDC failed %lu\n", cBitsPerPixel);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Create the DIB section with the same values */
|
|
*phbmpDIB = CreateDIBSection(*phdcDIB, pbmi, DIB_RGB_COLORS, ppvBits, 0, 0 );
|
|
if (*phbmpDIB == NULL)
|
|
{
|
|
printf("CreateDIBSection failed. %lu\n", cBitsPerPixel);
|
|
return FALSE;
|
|
}
|
|
|
|
if (SelectObject(*phdcDIB, *phbmpDIB) == NULL)
|
|
{
|
|
printf("SelectObject failed for %lu bpp DIB\n", cBitsPerPixel);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL GdiToolsInit(void)
|
|
{
|
|
/* Initialize a logical palette */
|
|
ghpal = CreatePalette((LOGPALETTE*)&gpal);
|
|
if (!ghpal)
|
|
{
|
|
printf("failed to create a palette\n");
|
|
return FALSE;
|
|
}
|
|
|
|
if (!InitPerBitDepth(1, 9, 9, &ghbmp1, &ghdcDIB1, &ghbmpDIB1, &gpvDIB1, 0) ||
|
|
!InitPerBitDepth(1, 9, 9, NULL, &ghdcDIB1_InvCol, &ghbmpDIB1_InvCol, &gpvDIB1_InvCol, FL_INVERT_COLORS) ||
|
|
!InitPerBitDepth(1, 9, 9, NULL, &ghdcDIB1_RB, &ghbmpDIB1_RB, &gpvDIB1_RB, FL_RED_BLUE) ||
|
|
!InitPerBitDepth(4, 5, 5, &ghbmp4, &ghdcDIB4, &ghbmpDIB4, &gpvDIB4, 0) ||
|
|
!InitPerBitDepth(8, 5, 5, &ghbmp8, &ghdcDIB8, &ghbmpDIB8, &gpvDIB8, 0) ||
|
|
!InitPerBitDepth(16, 8, 8, &ghbmp16, &ghdcDIB16, &ghbmpDIB16, &gpvDIB16, 0) ||
|
|
!InitPerBitDepth(24, 8, 8, &ghbmp24, &ghdcDIB24, &ghbmpDIB24, &gpvDIB24, 0) ||
|
|
!InitPerBitDepth(32, 8, 8, &ghbmp32, &ghdcDIB32, &ghbmpDIB32, &gpvDIB32, 0))
|
|
{
|
|
printf("failed to create objects\n");
|
|
return FALSE;
|
|
}
|
|
|
|
gpDIB32 = gpvDIB32;
|
|
|
|
/* Create an Info-DC */
|
|
ghdcInfo = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
|
|
if (!ghdcInfo)
|
|
{
|
|
printf("failed to create info DC\n");
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|