mirror of
https://github.com/reactos/reactos.git
synced 2024-11-10 00:34:39 +00:00
c424146e2c
svn path=/branches/cmake-bringup/; revision=48236
1623 lines
33 KiB
C
1623 lines
33 KiB
C
#include "precomp.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
HGDIOBJ stock_objects[NB_STOCK_OBJECTS]; // temp location.
|
|
|
|
HDC
|
|
FASTCALL
|
|
IntCreateDICW ( LPCWSTR lpwszDriver,
|
|
LPCWSTR lpwszDevice,
|
|
LPCWSTR lpwszOutput,
|
|
PDEVMODEW lpInitData,
|
|
ULONG iType )
|
|
{
|
|
UNICODE_STRING Device, Output;
|
|
HDC hDC = NULL;
|
|
BOOL Display = FALSE, Default = TRUE;
|
|
ULONG UMdhpdev = 0;
|
|
|
|
HANDLE hspool = NULL;
|
|
|
|
if ( !ghSpooler && !LoadTheSpoolerDrv())
|
|
{
|
|
DPRINT1("WinSpooler.Drv Did not load!\n");
|
|
}
|
|
else
|
|
{
|
|
DPRINT("WinSpooler.Drv Loaded! hMod -> 0x%x\n", ghSpooler);
|
|
}
|
|
|
|
if ((!lpwszDevice) && (!lpwszDriver))
|
|
{
|
|
Default = FALSE; // Ask Win32k to set Default device.
|
|
Display = TRUE; // Most likely to be DISPLAY.
|
|
}
|
|
else
|
|
{
|
|
if ((lpwszDevice) && (wcslen(lpwszDevice) != 0)) // First
|
|
{
|
|
if (!_wcsnicmp(lpwszDevice, L"\\\\.\\DISPLAY",11)) Display = TRUE;
|
|
RtlInitUnicodeString(&Device, lpwszDevice);
|
|
}
|
|
else
|
|
{
|
|
if (lpwszDriver) // Second
|
|
{
|
|
if ((!_wcsnicmp(lpwszDriver, L"DISPLAY",7)) ||
|
|
(!_wcsnicmp(lpwszDriver, L"\\\\.\\DISPLAY",11))) Display = TRUE;
|
|
RtlInitUnicodeString(&Device, lpwszDriver);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (lpwszOutput) RtlInitUnicodeString(&Output, lpwszOutput);
|
|
|
|
if (!Display)
|
|
{
|
|
//Handle Print device or something else.
|
|
DPRINT1("Not a DISPLAY device! %wZ\n", &Device);
|
|
}
|
|
|
|
hDC = NtGdiOpenDCW( (Default ? &Device : NULL),
|
|
(PDEVMODEW) lpInitData,
|
|
(lpwszOutput ? &Output : NULL),
|
|
iType, // DCW 0 and ICW 1.
|
|
Display,
|
|
hspool,
|
|
(PVOID) NULL, // NULL for now.
|
|
(PVOID) &UMdhpdev );
|
|
#if 0
|
|
// Handle something other than a normal dc object.
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
PLDC pLDC;
|
|
|
|
GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr);
|
|
|
|
pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC));
|
|
|
|
Dc_Attr->pvLDC = pLDC;
|
|
pLDC->hDC = hDC;
|
|
pLDC->iType = LDC_LDC; // 1 (init) local DC, 2 EMF LDC
|
|
DbgPrint("DC_ATTR Allocated -> 0x%x\n",Dc_Attr);
|
|
}
|
|
#endif
|
|
return hDC;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HDC
|
|
WINAPI
|
|
CreateCompatibleDC ( HDC hdc)
|
|
{
|
|
HDC rhDC;
|
|
// PDC_ATTR Dc_Attr;
|
|
|
|
rhDC = NtGdiCreateCompatibleDC(hdc);
|
|
#if 0
|
|
if ( hdc && rhDC)
|
|
{
|
|
if (GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
|
|
{
|
|
if ( Dc_Attr->pvLIcm ) IcmCompatibleDC(rhDC, hdc, Dc_Attr);
|
|
}
|
|
}
|
|
#endif
|
|
return rhDC;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HDC
|
|
WINAPI
|
|
CreateDCA (
|
|
LPCSTR lpszDriver,
|
|
LPCSTR lpszDevice,
|
|
LPCSTR lpszOutput,
|
|
CONST DEVMODEA * lpdvmInit
|
|
)
|
|
{
|
|
ANSI_STRING DriverA, DeviceA, OutputA;
|
|
UNICODE_STRING DriverU, DeviceU, OutputU;
|
|
LPDEVMODEW dvmInitW = NULL;
|
|
HDC hDC;
|
|
|
|
/*
|
|
* If needed, convert to Unicode
|
|
* any string parameter.
|
|
*/
|
|
|
|
if (NULL != lpszDriver)
|
|
{
|
|
RtlInitAnsiString(&DriverA, (LPSTR)lpszDriver);
|
|
RtlAnsiStringToUnicodeString(&DriverU, &DriverA, TRUE);
|
|
} else
|
|
DriverU.Buffer = NULL;
|
|
if (NULL != lpszDevice)
|
|
{
|
|
RtlInitAnsiString(&DeviceA, (LPSTR)lpszDevice);
|
|
RtlAnsiStringToUnicodeString(&DeviceU, &DeviceA, TRUE);
|
|
} else
|
|
DeviceU.Buffer = NULL;
|
|
if (NULL != lpszOutput)
|
|
{
|
|
RtlInitAnsiString(&OutputA, (LPSTR)lpszOutput);
|
|
RtlAnsiStringToUnicodeString(&OutputU, &OutputA, TRUE);
|
|
} else
|
|
OutputU.Buffer = NULL;
|
|
|
|
if ( lpdvmInit )
|
|
dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit);
|
|
|
|
hDC = IntCreateDICW ( DriverU.Buffer,
|
|
DeviceU.Buffer,
|
|
OutputU.Buffer,
|
|
lpdvmInit ? dvmInitW : NULL,
|
|
0 );
|
|
HEAP_free (dvmInitW);
|
|
/*
|
|
* Free Unicode parameters.
|
|
*/
|
|
RtlFreeUnicodeString(&DriverU);
|
|
RtlFreeUnicodeString(&DeviceU);
|
|
RtlFreeUnicodeString(&OutputU);
|
|
|
|
/*
|
|
* Return the possible DC handle.
|
|
*/
|
|
return hDC;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HDC
|
|
WINAPI
|
|
CreateDCW (
|
|
LPCWSTR lpwszDriver,
|
|
LPCWSTR lpwszDevice,
|
|
LPCWSTR lpwszOutput,
|
|
CONST DEVMODEW *lpInitData
|
|
)
|
|
{
|
|
|
|
return IntCreateDICW ( lpwszDriver,
|
|
lpwszDevice,
|
|
lpwszOutput,
|
|
(PDEVMODEW) lpInitData,
|
|
0 );
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HDC
|
|
WINAPI
|
|
CreateICW(
|
|
LPCWSTR lpszDriver,
|
|
LPCWSTR lpszDevice,
|
|
LPCWSTR lpszOutput,
|
|
CONST DEVMODEW *lpdvmInit
|
|
)
|
|
{
|
|
return IntCreateDICW ( lpszDriver,
|
|
lpszDevice,
|
|
lpszOutput,
|
|
(PDEVMODEW) lpdvmInit,
|
|
1 );
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HDC
|
|
WINAPI
|
|
CreateICA(
|
|
LPCSTR lpszDriver,
|
|
LPCSTR lpszDevice,
|
|
LPCSTR lpszOutput,
|
|
CONST DEVMODEA *lpdvmInit
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
LPWSTR lpszDriverW, lpszDeviceW, lpszOutputW;
|
|
LPDEVMODEW dvmInitW = NULL;
|
|
HDC rc = 0;
|
|
|
|
Status = HEAP_strdupA2W ( &lpszDriverW, lpszDriver );
|
|
if (!NT_SUCCESS (Status))
|
|
SetLastError (RtlNtStatusToDosError(Status));
|
|
else
|
|
{
|
|
Status = HEAP_strdupA2W ( &lpszDeviceW, lpszDevice );
|
|
if (!NT_SUCCESS (Status))
|
|
SetLastError (RtlNtStatusToDosError(Status));
|
|
else
|
|
{
|
|
Status = HEAP_strdupA2W ( &lpszOutputW, lpszOutput );
|
|
if (!NT_SUCCESS (Status))
|
|
SetLastError (RtlNtStatusToDosError(Status));
|
|
else
|
|
{
|
|
if ( lpdvmInit )
|
|
dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit);
|
|
|
|
rc = IntCreateDICW ( lpszDriverW,
|
|
lpszDeviceW,
|
|
lpszOutputW,
|
|
lpdvmInit ? dvmInitW : NULL,
|
|
1 );
|
|
HEAP_free (dvmInitW);
|
|
HEAP_free ( lpszOutputW );
|
|
}
|
|
HEAP_free ( lpszDeviceW );
|
|
}
|
|
HEAP_free ( lpszDriverW );
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
DeleteDC(HDC hDC)
|
|
{
|
|
BOOL Ret = TRUE;
|
|
PLDC pLDC = NULL;
|
|
HANDLE hPrinter = NULL;
|
|
ULONG hType = GDI_HANDLE_GET_TYPE(hDC);
|
|
|
|
pLDC = GdiGetLDC(hDC);
|
|
|
|
if (hType != GDILoObjType_LO_DC_TYPE)
|
|
{
|
|
|
|
if ( !pLDC || hType == GDILoObjType_LO_METADC16_TYPE)
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return FALSE;
|
|
}
|
|
if (pLDC->Flags & LDC_INIT_DOCUMENT) AbortDoc(hDC);
|
|
if (pLDC->hPrinter)
|
|
{
|
|
DocumentEventEx(NULL, pLDC->hPrinter, hDC, DOCUMENTEVENT_DELETEDC, 0, NULL, 0, NULL);
|
|
hPrinter = pLDC->hPrinter;
|
|
pLDC->hPrinter = NULL;
|
|
}
|
|
}
|
|
|
|
Ret = NtGdiDeleteObjectApp(hDC);
|
|
|
|
if (Ret && pLDC )
|
|
{
|
|
DPRINT1("Delete the Local DC structure\n");
|
|
LocalFree( pLDC );
|
|
}
|
|
if (hPrinter) fpClosePrinter(hPrinter);
|
|
return Ret;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
DeleteObject(HGDIOBJ hObject)
|
|
{
|
|
UINT Type = 0;
|
|
|
|
/* From Wine: DeleteObject does not SetLastError() on a null object */
|
|
if(!hObject) return FALSE;
|
|
|
|
if (0 != ((DWORD) hObject & GDI_HANDLE_STOCK_MASK))
|
|
{ // Relax! This is a normal return!
|
|
DPRINT("Trying to delete system object 0x%x\n", hObject);
|
|
return TRUE;
|
|
}
|
|
// If you dont own it?! Get OUT!
|
|
if(!GdiIsHandleValid(hObject)) return FALSE;
|
|
|
|
Type = GDI_HANDLE_GET_TYPE(hObject);
|
|
|
|
if ((Type == GDI_OBJECT_TYPE_METAFILE) ||
|
|
(Type == GDI_OBJECT_TYPE_ENHMETAFILE))
|
|
return FALSE;
|
|
|
|
switch (Type)
|
|
{
|
|
case GDI_OBJECT_TYPE_DC:
|
|
return DeleteDC((HDC) hObject);
|
|
case GDI_OBJECT_TYPE_COLORSPACE:
|
|
return NtGdiDeleteColorSpace((HCOLORSPACE) hObject);
|
|
case GDI_OBJECT_TYPE_REGION:
|
|
return DeleteRegion((HRGN) hObject);
|
|
#if 0
|
|
case GDI_OBJECT_TYPE_METADC:
|
|
return MFDRV_DeleteObject( hObject );
|
|
case GDI_OBJECT_TYPE_EMF:
|
|
{
|
|
PLDC pLDC = GdiGetLDC(hObject);
|
|
if ( !pLDC ) return FALSE;
|
|
return EMFDRV_DeleteObject( hObject );
|
|
}
|
|
#endif
|
|
case GDI_OBJECT_TYPE_FONT:
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
case GDI_OBJECT_TYPE_PEN:
|
|
{
|
|
PBRUSH_ATTR Brh_Attr;
|
|
PTEB pTeb;
|
|
|
|
if ((!GdiGetHandleUserData(hObject, (DWORD)Type, (PVOID) &Brh_Attr)) ||
|
|
(Brh_Attr == NULL) ) break;
|
|
|
|
pTeb = NtCurrentTeb();
|
|
|
|
if (pTeb->Win32ThreadInfo == NULL) break;
|
|
|
|
if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
|
|
{
|
|
PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
|
|
pTeb->GdiTebBatch.Offset);
|
|
pgO->gbHdr.Cmd = GdiBCDelObj;
|
|
pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
|
|
pgO->hgdiobj = hObject;
|
|
|
|
pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
|
|
pTeb->GdiBatchCount++;
|
|
if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
|
|
return TRUE;
|
|
}
|
|
break;
|
|
}
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
default:
|
|
break;
|
|
}
|
|
return NtGdiDeleteObjectApp(hObject);
|
|
}
|
|
|
|
INT
|
|
WINAPI
|
|
GetArcDirection( HDC hdc )
|
|
{
|
|
return GetDCDWord( hdc, GdiGetArcDirection, 0);
|
|
}
|
|
|
|
|
|
INT
|
|
WINAPI
|
|
SetArcDirection( HDC hdc, INT nDirection )
|
|
{
|
|
return GetAndSetDCDWord( hdc, GdiGetSetArcDirection, nDirection, 0, 0, 0 );
|
|
}
|
|
|
|
|
|
HGDIOBJ
|
|
WINAPI
|
|
GetDCObject( HDC hDC, INT iType)
|
|
{
|
|
if((iType == GDI_OBJECT_TYPE_BRUSH) ||
|
|
(iType == GDI_OBJECT_TYPE_EXTPEN)||
|
|
(iType == GDI_OBJECT_TYPE_PEN) ||
|
|
(iType == GDI_OBJECT_TYPE_COLORSPACE))
|
|
{
|
|
HGDIOBJ hGO = NULL;
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
if (!hDC) return hGO;
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return NULL;
|
|
|
|
switch (iType)
|
|
{
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
|
hGO = Dc_Attr->hbrush;
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
case GDI_OBJECT_TYPE_PEN:
|
|
hGO = Dc_Attr->hpen;
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_COLORSPACE:
|
|
hGO = Dc_Attr->hColorSpace;
|
|
break;
|
|
}
|
|
return hGO;
|
|
}
|
|
return NtGdiGetDCObject( hDC, iType );
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
HGDIOBJ
|
|
WINAPI
|
|
GetCurrentObject(HDC hdc,
|
|
UINT uObjectType)
|
|
{
|
|
switch(uObjectType)
|
|
{
|
|
case OBJ_EXTPEN:
|
|
case OBJ_PEN:
|
|
uObjectType = GDI_OBJECT_TYPE_PEN;
|
|
break;
|
|
case OBJ_BRUSH:
|
|
uObjectType = GDI_OBJECT_TYPE_BRUSH;
|
|
break;
|
|
case OBJ_PAL:
|
|
uObjectType = GDI_OBJECT_TYPE_PALETTE;
|
|
break;
|
|
case OBJ_FONT:
|
|
uObjectType = GDI_OBJECT_TYPE_FONT;
|
|
break;
|
|
case OBJ_BITMAP:
|
|
uObjectType = GDI_OBJECT_TYPE_BITMAP;
|
|
break;
|
|
case OBJ_COLORSPACE:
|
|
uObjectType = GDI_OBJECT_TYPE_COLORSPACE;
|
|
break;
|
|
/* tests show that OBJ_REGION is explicitly ignored */
|
|
case OBJ_REGION:
|
|
return NULL;
|
|
/* the SDK only mentions those above */
|
|
default:
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return NULL;
|
|
}
|
|
return GetDCObject(hdc, uObjectType);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
int
|
|
WINAPI
|
|
GetDeviceCaps(HDC hDC,
|
|
int i)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
PLDC pLDC;
|
|
PDEVCAPS pDevCaps = GdiDevCaps; // Primary display device capabilities.
|
|
DPRINT("Device CAPS1\n");
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
{
|
|
if ( i == TECHNOLOGY) return DT_METAFILE;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
pLDC = GdiGetLDC(hDC);
|
|
if ( !pLDC )
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return 0;
|
|
}
|
|
if (!(pLDC->Flags & LDC_DEVCAPS))
|
|
{
|
|
if (!NtGdiGetDeviceCapsAll(hDC, &pLDC->DevCaps))
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
pLDC->Flags |= LDC_DEVCAPS;
|
|
}
|
|
pDevCaps = &pLDC->DevCaps;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
|
|
return 0;
|
|
if (!(Dc_Attr->ulDirty_ & DC_PRIMARY_DISPLAY) )
|
|
return NtGdiGetDeviceCaps(hDC,i);
|
|
}
|
|
DPRINT("Device CAPS2\n");
|
|
|
|
switch (i)
|
|
{
|
|
case DRIVERVERSION:
|
|
return pDevCaps->ulVersion;
|
|
|
|
case TECHNOLOGY:
|
|
return pDevCaps->ulTechnology;
|
|
|
|
case HORZSIZE:
|
|
return pDevCaps->ulHorzSize;
|
|
|
|
case VERTSIZE:
|
|
return pDevCaps->ulVertSize;
|
|
|
|
case HORZRES:
|
|
return pDevCaps->ulHorzRes;
|
|
|
|
case VERTRES:
|
|
return pDevCaps->ulVertRes;
|
|
|
|
case LOGPIXELSX:
|
|
return pDevCaps->ulLogPixelsX;
|
|
|
|
case LOGPIXELSY:
|
|
return pDevCaps->ulLogPixelsY;
|
|
|
|
case BITSPIXEL:
|
|
return pDevCaps->ulBitsPixel;
|
|
|
|
case PLANES:
|
|
return pDevCaps->ulPlanes;
|
|
|
|
case NUMBRUSHES:
|
|
return -1;
|
|
|
|
case NUMPENS:
|
|
return pDevCaps->ulNumPens;
|
|
|
|
case NUMFONTS:
|
|
return pDevCaps->ulNumFonts;
|
|
|
|
case NUMCOLORS:
|
|
return pDevCaps->ulNumColors;
|
|
|
|
case ASPECTX:
|
|
return pDevCaps->ulAspectX;
|
|
|
|
case ASPECTY:
|
|
return pDevCaps->ulAspectY;
|
|
|
|
case ASPECTXY:
|
|
return pDevCaps->ulAspectXY;
|
|
|
|
case CLIPCAPS:
|
|
return CP_RECTANGLE;
|
|
|
|
case SIZEPALETTE:
|
|
return pDevCaps->ulSizePalette;
|
|
|
|
case NUMRESERVED:
|
|
return 20;
|
|
|
|
case COLORRES:
|
|
return pDevCaps->ulColorRes;
|
|
|
|
case DESKTOPVERTRES:
|
|
return pDevCaps->ulVertRes;
|
|
|
|
case DESKTOPHORZRES:
|
|
return pDevCaps->ulHorzRes;
|
|
|
|
case BLTALIGNMENT:
|
|
return pDevCaps->ulBltAlignment;
|
|
|
|
case SHADEBLENDCAPS:
|
|
return pDevCaps->ulShadeBlend;
|
|
|
|
case COLORMGMTCAPS:
|
|
return pDevCaps->ulColorMgmtCaps;
|
|
|
|
case PHYSICALWIDTH:
|
|
return pDevCaps->ulPhysicalWidth;
|
|
|
|
case PHYSICALHEIGHT:
|
|
return pDevCaps->ulPhysicalHeight;
|
|
|
|
case PHYSICALOFFSETX:
|
|
return pDevCaps->ulPhysicalOffsetX;
|
|
|
|
case PHYSICALOFFSETY:
|
|
return pDevCaps->ulPhysicalOffsetY;
|
|
|
|
case VREFRESH:
|
|
return pDevCaps->ulVRefresh;
|
|
|
|
case RASTERCAPS:
|
|
return pDevCaps->ulRasterCaps;
|
|
|
|
case CURVECAPS:
|
|
return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
|
|
CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
|
|
|
|
case LINECAPS:
|
|
return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
|
|
LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
|
|
|
|
case POLYGONALCAPS:
|
|
return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
|
|
PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
|
|
|
|
case TEXTCAPS:
|
|
return pDevCaps->ulTextCaps;
|
|
|
|
case PDEVICESIZE:
|
|
case SCALINGFACTORX:
|
|
case SCALINGFACTORY:
|
|
default:
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
GetRelAbs(
|
|
HDC hdc,
|
|
DWORD dwIgnore
|
|
)
|
|
{
|
|
return GetDCDWord( hdc, GdiGetRelAbs, 0);
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
INT
|
|
WINAPI
|
|
SetRelAbs(
|
|
HDC hdc,
|
|
INT Mode
|
|
)
|
|
{
|
|
return GetAndSetDCDWord( hdc, GdiGetSetRelAbs, Mode, 0, 0, 0 );
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
GetAndSetDCDWord( HDC hDC, INT u, DWORD dwIn, DWORD Unk1, DWORD Unk2, DWORD Unk3 )
|
|
{
|
|
BOOL Ret = TRUE;
|
|
// Handle something other than a normal dc object.
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
return 0; //call MFDRV
|
|
else
|
|
{
|
|
PLDC pLDC = GdiGetLDC(hDC);
|
|
if ( !pLDC )
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return 0;
|
|
}
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
{
|
|
Ret = TRUE; //call EMFDRV
|
|
if (Ret)
|
|
return u;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
Ret = NtGdiGetAndSetDCDword( hDC, u, dwIn, (DWORD*) &u );
|
|
if (Ret)
|
|
return u;
|
|
else
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
GetDCDWord( HDC hDC, INT u, DWORD Result )
|
|
{
|
|
BOOL Ret = NtGdiGetDCDword( hDC, u, (DWORD*) &u );
|
|
if (!Ret) return Result;
|
|
else return u;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetAspectRatioFilterEx(
|
|
HDC hdc,
|
|
LPSIZE lpAspectRatio
|
|
)
|
|
{
|
|
return NtGdiGetDCPoint( hdc, GdiGetAspectRatioFilter, (LPPOINT) lpAspectRatio );
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
BOOL
|
|
WINAPI
|
|
GetDCOrgEx(
|
|
HDC hdc,
|
|
LPPOINT lpPoint
|
|
)
|
|
{
|
|
return NtGdiGetDCPoint( hdc, GdiGetDCOrg, lpPoint );
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
LONG
|
|
WINAPI
|
|
GetDCOrg(
|
|
HDC hdc
|
|
)
|
|
{
|
|
// Officially obsolete by Microsoft
|
|
POINT Pt;
|
|
if (!GetDCOrgEx(hdc, &Pt))
|
|
return 0;
|
|
return(MAKELONG(Pt.x, Pt.y));
|
|
}
|
|
|
|
|
|
int
|
|
GetNonFontObject(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
|
|
{
|
|
INT dwType;
|
|
|
|
hGdiObj = (HANDLE)GdiFixUpHandle(hGdiObj);
|
|
dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
|
|
|
|
if (!lpBuffer) // Should pass it all to Win32k and let god sort it out. ;^)
|
|
{
|
|
switch(dwType)
|
|
{
|
|
case GDI_OBJECT_TYPE_PEN:
|
|
return sizeof(LOGPEN);
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
|
return sizeof(LOGBRUSH);
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
return sizeof(BITMAP);
|
|
case GDI_OBJECT_TYPE_PALETTE:
|
|
return sizeof(WORD);
|
|
case GDI_OBJECT_TYPE_EXTPEN: /* we don't know the size, ask win32k */
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch(dwType)
|
|
{
|
|
case GDI_OBJECT_TYPE_PEN: //Check the structures and see if A & W are the same.
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
case GDI_OBJECT_TYPE_BRUSH: // Mixing Apples and Oranges?
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
case GDI_OBJECT_TYPE_PALETTE:
|
|
return NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
|
|
|
|
case GDI_OBJECT_TYPE_DC:
|
|
case GDI_OBJECT_TYPE_REGION:
|
|
case GDI_OBJECT_TYPE_METAFILE:
|
|
case GDI_OBJECT_TYPE_ENHMETAFILE:
|
|
case GDI_OBJECT_TYPE_EMF:
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
int
|
|
WINAPI
|
|
GetObjectA(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
|
|
{
|
|
ENUMLOGFONTEXDVW LogFont;
|
|
DWORD dwType;
|
|
INT Result = 0;
|
|
|
|
dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
|
|
|
|
if(dwType == GDI_OBJECT_TYPE_COLORSPACE) //Stays here, processes struct A
|
|
{
|
|
SetLastError(ERROR_NOT_SUPPORTED);
|
|
return 0;
|
|
}
|
|
|
|
if (dwType == GDI_OBJECT_TYPE_FONT)
|
|
{
|
|
if (!lpBuffer)
|
|
{
|
|
return sizeof(LOGFONTA);
|
|
}
|
|
if (cbSize == 0)
|
|
{
|
|
/* Windows does not SetLastError() */
|
|
return 0;
|
|
}
|
|
// ENUMLOGFONTEXDVW is the default size and should be the structure for
|
|
// Entry->KernelData for Font objects.
|
|
Result = NtGdiExtGetObjectW(hGdiObj, sizeof(ENUMLOGFONTEXDVW), &LogFont);
|
|
|
|
if (0 == Result)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
switch (cbSize)
|
|
{
|
|
case sizeof(ENUMLOGFONTEXDVA):
|
|
// need to move more here.
|
|
case sizeof(ENUMLOGFONTEXA):
|
|
EnumLogFontExW2A( (LPENUMLOGFONTEXA) lpBuffer, &LogFont.elfEnumLogfontEx );
|
|
break;
|
|
|
|
case sizeof(ENUMLOGFONTA):
|
|
// Same here, maybe? Check the structures.
|
|
case sizeof(EXTLOGFONTA):
|
|
// Same here
|
|
case sizeof(LOGFONTA):
|
|
LogFontW2A((LPLOGFONTA) lpBuffer, &LogFont.elfEnumLogfontEx.elfLogFont);
|
|
break;
|
|
|
|
default:
|
|
SetLastError(ERROR_BUFFER_OVERFLOW);
|
|
return 0;
|
|
}
|
|
return cbSize;
|
|
}
|
|
|
|
return GetNonFontObject(hGdiObj, cbSize, lpBuffer);
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
int
|
|
WINAPI
|
|
GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
|
|
{
|
|
DWORD dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
|
|
INT Result = 0;
|
|
|
|
/*
|
|
Check List:
|
|
MSDN, "This can be a handle to one of the following: logical bitmap, a brush,
|
|
a font, a palette, a pen, or a device independent bitmap created by calling
|
|
the CreateDIBSection function."
|
|
*/
|
|
if(dwType == GDI_OBJECT_TYPE_COLORSPACE) //Stays here, processes struct W
|
|
{
|
|
SetLastError(ERROR_NOT_SUPPORTED); // Not supported yet.
|
|
return 0;
|
|
}
|
|
|
|
if (dwType == GDI_OBJECT_TYPE_FONT)
|
|
{
|
|
if (!lpBuffer)
|
|
{
|
|
return sizeof(LOGFONTW);
|
|
}
|
|
|
|
if (cbSize == 0)
|
|
{
|
|
/* Windows does not SetLastError() */
|
|
return 0;
|
|
}
|
|
// Poorly written apps are not ReactOS problem!
|
|
// We fix it here if the size is larger than the default size.
|
|
if( cbSize > (int)sizeof(ENUMLOGFONTEXDVW) ) cbSize = sizeof(ENUMLOGFONTEXDVW);
|
|
|
|
Result = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer); // Should handle the copy.
|
|
|
|
if (0 == Result)
|
|
{
|
|
return 0;
|
|
}
|
|
return cbSize;
|
|
}
|
|
|
|
return GetNonFontObject(hGdiObj, cbSize, lpBuffer);
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
COLORREF
|
|
WINAPI
|
|
GetDCBrushColor(
|
|
HDC hdc
|
|
)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return CLR_INVALID;
|
|
return (COLORREF) Dc_Attr->ulBrushClr;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
COLORREF
|
|
WINAPI
|
|
GetDCPenColor(
|
|
HDC hdc
|
|
)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return CLR_INVALID;
|
|
return (COLORREF) Dc_Attr->ulPenClr;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
COLORREF
|
|
WINAPI
|
|
SetDCBrushColor(
|
|
HDC hdc,
|
|
COLORREF crColor
|
|
)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
COLORREF OldColor = CLR_INVALID;
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
|
|
else
|
|
{
|
|
OldColor = (COLORREF) Dc_Attr->ulBrushClr;
|
|
Dc_Attr->ulBrushClr = (ULONG) crColor;
|
|
|
|
if ( Dc_Attr->crBrushClr != crColor ) // if same, don't force a copy.
|
|
{
|
|
Dc_Attr->ulDirty_ |= DIRTY_FILL;
|
|
Dc_Attr->crBrushClr = crColor;
|
|
}
|
|
}
|
|
return OldColor;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
COLORREF
|
|
WINAPI
|
|
SetDCPenColor(
|
|
HDC hdc,
|
|
COLORREF crColor
|
|
)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
COLORREF OldColor = CLR_INVALID;
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
|
|
else
|
|
{
|
|
OldColor = (COLORREF) Dc_Attr->ulPenClr;
|
|
Dc_Attr->ulPenClr = (ULONG) crColor;
|
|
|
|
if ( Dc_Attr->crPenClr != crColor )
|
|
{
|
|
Dc_Attr->ulDirty_ |= DIRTY_LINE;
|
|
Dc_Attr->crPenClr = crColor;
|
|
}
|
|
}
|
|
return OldColor;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
COLORREF
|
|
WINAPI
|
|
GetBkColor(HDC hdc)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
return Dc_Attr->ulBackgroundClr;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
COLORREF
|
|
WINAPI
|
|
SetBkColor(
|
|
HDC hdc,
|
|
COLORREF crColor
|
|
)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
COLORREF OldColor = CLR_INVALID;
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
|
|
#if 0
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
return MFDRV_SetBkColor( hDC, crColor );
|
|
else
|
|
{
|
|
PLDC pLDC = Dc_Attr->pvLDC;
|
|
if ( !pLDC )
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return FALSE;
|
|
}
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
{
|
|
return EMFDRV_SetBkColor( hDC, crColor );
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
OldColor = (COLORREF) Dc_Attr->ulBackgroundClr;
|
|
Dc_Attr->ulBackgroundClr = (ULONG) crColor;
|
|
|
|
if ( Dc_Attr->crBackgroundClr != crColor )
|
|
{
|
|
Dc_Attr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL);
|
|
Dc_Attr->crBackgroundClr = crColor;
|
|
}
|
|
return OldColor;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
int
|
|
WINAPI
|
|
GetBkMode(HDC hdc)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
return Dc_Attr->lBkMode;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
int
|
|
WINAPI
|
|
SetBkMode(HDC hdc,
|
|
int iBkMode)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
INT OldMode = 0;
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
|
|
#if 0
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
return MFDRV_SetBkMode( hdc, iBkMode )
|
|
else
|
|
{
|
|
PLDC pLDC = Dc_Attr->pvLDC;
|
|
if ( !pLDC )
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return FALSE;
|
|
}
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
{
|
|
return EMFDRV_SetBkMode( hdc, iBkMode )
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
OldMode = Dc_Attr->lBkMode;
|
|
Dc_Attr->jBkMode = iBkMode; // Processed
|
|
Dc_Attr->lBkMode = iBkMode; // Raw
|
|
return OldMode;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
int
|
|
WINAPI
|
|
GetPolyFillMode(HDC hdc)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
return Dc_Attr->lFillMode;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
int
|
|
WINAPI
|
|
SetPolyFillMode(HDC hdc,
|
|
int iPolyFillMode)
|
|
{
|
|
INT fmode;
|
|
PDC_ATTR Dc_Attr;
|
|
#if 0
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
return MFDRV_SetPolyFillMode( hdc, iPolyFillMode )
|
|
else
|
|
{
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
if ( !pLDC )
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return FALSE;
|
|
}
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
{
|
|
return EMFDRV_SetPolyFillMode( hdc, iPolyFillMode )
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
|
|
if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
|
|
{
|
|
if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
|
|
{
|
|
NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
|
|
Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
|
|
}
|
|
}
|
|
|
|
fmode = Dc_Attr->lFillMode;
|
|
Dc_Attr->lFillMode = iPolyFillMode;
|
|
|
|
return fmode;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
int
|
|
WINAPI
|
|
GetGraphicsMode(HDC hdc)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
return Dc_Attr->iGraphicsMode;
|
|
}
|
|
|
|
/*
|
|
* @unimplemented
|
|
*/
|
|
int
|
|
WINAPI
|
|
SetGraphicsMode(HDC hdc,
|
|
int iMode)
|
|
{
|
|
INT oMode;
|
|
PDC_ATTR Dc_Attr;
|
|
if ((iMode < GM_COMPATIBLE) || (iMode > GM_ADVANCED))
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return 0;
|
|
}
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
|
|
if (iMode == Dc_Attr->iGraphicsMode) return iMode;
|
|
|
|
if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
|
|
{
|
|
if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
|
|
{
|
|
NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
|
|
Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
|
|
}
|
|
}
|
|
/* One would think that setting the graphics mode to GM_COMPATIBLE
|
|
* would also reset the world transformation matrix to the unity
|
|
* matrix. However, in Windows, this is not the case. This doesn't
|
|
* make a lot of sense to me, but that's the way it is.
|
|
*/
|
|
oMode = Dc_Attr->iGraphicsMode;
|
|
Dc_Attr->iGraphicsMode = iMode;
|
|
|
|
return oMode;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HDC
|
|
WINAPI
|
|
ResetDCW(
|
|
HDC hdc,
|
|
CONST DEVMODEW *lpInitData
|
|
)
|
|
{
|
|
NtGdiResetDC ( hdc, (PDEVMODEW)lpInitData, NULL, NULL, NULL);
|
|
return hdc;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HDC
|
|
WINAPI
|
|
ResetDCA(
|
|
HDC hdc,
|
|
CONST DEVMODEA *lpInitData
|
|
)
|
|
{
|
|
LPDEVMODEW InitDataW;
|
|
|
|
InitDataW = GdiConvertToDevmodeW((LPDEVMODEA)lpInitData);
|
|
|
|
NtGdiResetDC ( hdc, InitDataW, NULL, NULL, NULL);
|
|
HEAP_free(InitDataW);
|
|
return hdc;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
DWORD
|
|
WINAPI
|
|
GetObjectType(
|
|
HGDIOBJ h
|
|
)
|
|
{
|
|
DWORD Ret = 0;
|
|
|
|
if(GdiIsHandleValid(h))
|
|
{
|
|
LONG Type = GDI_HANDLE_GET_TYPE(h);
|
|
switch(Type)
|
|
{
|
|
case GDI_OBJECT_TYPE_PEN:
|
|
Ret = OBJ_PEN;
|
|
break;
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
|
Ret = OBJ_BRUSH;
|
|
break;
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
Ret = OBJ_BITMAP;
|
|
break;
|
|
case GDI_OBJECT_TYPE_FONT:
|
|
Ret = OBJ_FONT;
|
|
break;
|
|
case GDI_OBJECT_TYPE_PALETTE:
|
|
Ret = OBJ_PAL;
|
|
break;
|
|
case GDI_OBJECT_TYPE_REGION:
|
|
Ret = OBJ_REGION;
|
|
break;
|
|
case GDI_OBJECT_TYPE_DC:
|
|
if ( GetDCDWord( h, GdiGetIsMemDc, 0))
|
|
{
|
|
Ret = OBJ_MEMDC;
|
|
}
|
|
else
|
|
Ret = OBJ_DC;
|
|
break;
|
|
case GDI_OBJECT_TYPE_COLORSPACE:
|
|
Ret = OBJ_COLORSPACE;
|
|
break;
|
|
case GDI_OBJECT_TYPE_METAFILE:
|
|
Ret = OBJ_METAFILE;
|
|
break;
|
|
case GDI_OBJECT_TYPE_ENHMETAFILE:
|
|
Ret = OBJ_ENHMETAFILE;
|
|
break;
|
|
case GDI_OBJECT_TYPE_METADC:
|
|
Ret = OBJ_METADC;
|
|
break;
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
Ret = OBJ_EXTPEN;
|
|
break;
|
|
|
|
default:
|
|
DPRINT1("GetObjectType: Magic 0x%08x not implemented\n", Type);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
/* From Wine: GetObjectType does SetLastError() on a null object */
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return Ret;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HGDIOBJ
|
|
WINAPI
|
|
GetStockObject(
|
|
INT h
|
|
)
|
|
{
|
|
HGDIOBJ Ret = NULL;
|
|
if ((h < 0) || (h >= NB_STOCK_OBJECTS)) return Ret;
|
|
Ret = stock_objects[h];
|
|
if (!Ret)
|
|
{
|
|
HGDIOBJ Obj = NtGdiGetStockObject( h );
|
|
|
|
if (GdiIsHandleValid(Obj))
|
|
{
|
|
stock_objects[h] = Obj;
|
|
return Obj;
|
|
}// Returns Null anyway.
|
|
}
|
|
return Ret;
|
|
}
|
|
|
|
/* FIXME: include correct header */
|
|
HPALETTE WINAPI NtUserSelectPalette(HDC hDC,
|
|
HPALETTE hpal,
|
|
BOOL ForceBackground);
|
|
|
|
HPALETTE
|
|
WINAPI
|
|
SelectPalette(
|
|
HDC hDC,
|
|
HPALETTE hPal,
|
|
BOOL bForceBackground)
|
|
{
|
|
#if 0
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
return MFDRV_SelectPalette( hDC, hPal, bForceBackground);
|
|
else
|
|
{
|
|
PLDC pLDC = GdiGetLDC(hDC);
|
|
if ( !pLDC )
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return NULL;
|
|
}
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
{
|
|
if return EMFDRV_SelectPalette( hDC, hPal, bForceBackground);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return NtUserSelectPalette(hDC, hPal, bForceBackground);
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
int
|
|
WINAPI
|
|
GetMapMode(HDC hdc)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
return Dc_Attr->iMapMode;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
INT
|
|
WINAPI
|
|
SetMapMode(
|
|
HDC hdc,
|
|
INT Mode
|
|
)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
#if 0
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
return MFDRV_SetMapMode(hdc, Mode);
|
|
else
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return 0;
|
|
}
|
|
#endif
|
|
// Force change if Isotropic is set for recompute.
|
|
if ((Mode != Dc_Attr->iMapMode) || (Mode == MM_ISOTROPIC))
|
|
{
|
|
Dc_Attr->ulDirty_ &= ~SLOW_WIDTHS;
|
|
return GetAndSetDCDWord( hdc, GdiGetSetMapMode, Mode, 0, 0, 0 );
|
|
}
|
|
return Dc_Attr->iMapMode;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
int
|
|
WINAPI
|
|
GetStretchBltMode(HDC hdc)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
return Dc_Attr->lStretchBltMode;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
int
|
|
WINAPI
|
|
SetStretchBltMode(HDC hdc, int iStretchMode)
|
|
{
|
|
INT oSMode;
|
|
PDC_ATTR Dc_Attr;
|
|
#if 0
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
{
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
return MFDRV_SetStretchBltMode( hdc, iStretchMode);
|
|
else
|
|
{
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
if ( !pLDC )
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return 0;
|
|
}
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
{
|
|
return EMFDRV_SetStretchBltMode( hdc, iStretchMode);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
|
|
|
oSMode = Dc_Attr->lStretchBltMode;
|
|
Dc_Attr->lStretchBltMode = iStretchMode;
|
|
|
|
// Wine returns an error here. We set the default.
|
|
if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
|
|
|
|
Dc_Attr->jStretchBltMode = iStretchMode;
|
|
|
|
return oSMode;
|
|
}
|
|
|
|
/*
|
|
* @implemented
|
|
*/
|
|
HFONT
|
|
WINAPI
|
|
GetHFONT(HDC hdc)
|
|
{
|
|
PDC_ATTR Dc_Attr;
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return NULL;
|
|
return Dc_Attr->hlfntNew;
|
|
}
|
|
|
|
|
|
/*
|
|
* @implemented
|
|
*
|
|
*/
|
|
HGDIOBJ
|
|
WINAPI
|
|
SelectObject(HDC hDC,
|
|
HGDIOBJ hGdiObj)
|
|
{
|
|
PDC_ATTR pDc_Attr;
|
|
HGDIOBJ hOldObj = NULL;
|
|
UINT uType;
|
|
|
|
if(!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
|
|
{
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
return NULL;
|
|
}
|
|
|
|
hGdiObj = GdiFixUpHandle(hGdiObj);
|
|
if (!GdiIsHandleValid(hGdiObj))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
uType = GDI_HANDLE_GET_TYPE(hGdiObj);
|
|
|
|
switch (uType)
|
|
{
|
|
case GDI_OBJECT_TYPE_REGION:
|
|
return (HGDIOBJ)ExtSelectClipRgn(hDC, hGdiObj, RGN_COPY);
|
|
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
return NtGdiSelectBitmap(hDC, hGdiObj);
|
|
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
|
hOldObj = pDc_Attr->hbrush;
|
|
pDc_Attr->ulDirty_ |= DC_BRUSH_DIRTY;
|
|
pDc_Attr->hbrush = hGdiObj;
|
|
return hOldObj;
|
|
// return NtGdiSelectBrush(hDC, hGdiObj);
|
|
|
|
case GDI_OBJECT_TYPE_PEN:
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
hOldObj = pDc_Attr->hpen;
|
|
pDc_Attr->ulDirty_ |= DC_PEN_DIRTY;
|
|
pDc_Attr->hpen = hGdiObj;
|
|
return hOldObj;
|
|
// return NtGdiSelectPen(hDC, hGdiObj);
|
|
|
|
case GDI_OBJECT_TYPE_FONT:
|
|
hOldObj = pDc_Attr->hlfntNew;
|
|
if (hOldObj == hGdiObj) return hOldObj;
|
|
|
|
pDc_Attr->ulDirty_ &= ~SLOW_WIDTHS;
|
|
pDc_Attr->ulDirty_ |= DIRTY_CHARSET;
|
|
pDc_Attr->hlfntNew = hGdiObj;
|
|
|
|
if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
|
|
{
|
|
PGDIBSOBJECT pgO;
|
|
|
|
pgO = GdiAllocBatchCommand(hDC, GdiBCSelObj);
|
|
if (pgO)
|
|
{
|
|
pgO->hgdiobj = hGdiObj;
|
|
return hOldObj;
|
|
}
|
|
}
|
|
|
|
// default for select object font
|
|
return NtGdiSelectFont(hDC, hGdiObj);
|
|
|
|
#if 0
|
|
case GDI_OBJECT_TYPE_METADC:
|
|
return MFDRV_SelectObject( hDC, hGdiObj);
|
|
case GDI_OBJECT_TYPE_EMF:
|
|
PLDC pLDC = GdiGetLDC(hDC);
|
|
if ( !pLDC ) return NULL;
|
|
return EMFDRV_SelectObject( hDC, hGdiObj);
|
|
#endif
|
|
case GDI_OBJECT_TYPE_COLORSPACE:
|
|
SetColorSpace(hDC, (HCOLORSPACE) hGdiObj);
|
|
return NULL;
|
|
|
|
case GDI_OBJECT_TYPE_PALETTE:
|
|
default:
|
|
SetLastError(ERROR_INVALID_FUNCTION);
|
|
return NULL;
|
|
}
|
|
|
|
return NULL;
|
|
}
|