📄 dc.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 ((!lpwszDevice) && (!lpwszDriver))
{
Default = FALSE; // Ask Win32k to set Default device.
Display = TRUE; // Most likely to be DISPLAY.
}
else
{
if (lpwszDevice) // 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.
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, (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
STDCALL
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
STDCALL
CreateDCW (
LPCWSTR lpwszDriver,
LPCWSTR lpwszDevice,
LPCWSTR lpwszOutput,
CONST DEVMODEW *lpInitData
)
{
return IntCreateDICW ( lpwszDriver,
lpwszDevice,
lpwszOutput,
(PDEVMODEW) lpInitData,
0 );
}
/*
* @implemented
*/
HDC
STDCALL
CreateICW(
LPCWSTR lpszDriver,
LPCWSTR lpszDevice,
LPCWSTR lpszOutput,
CONST DEVMODEW *lpdvmInit
)
{
return IntCreateDICW ( lpszDriver,
lpszDevice,
lpszOutput,
(PDEVMODEW) lpdvmInit,
1 );
}
/*
* @implemented
*/
HDC
STDCALL
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
STDCALL
DeleteDC(HDC hDC)
{
BOOL Ret = TRUE;
#if 0
PDC_ATTR Dc_Attr;
PLDC pLDC;
if (!GdiGetHandleUserData((HGDIOBJ) hDC, (PVOID) &Dc_Attr)) return FALSE;
if ( Dc_Attr )
{
pLDC = Dc_Attr->pvLDC;
if ( pLDC )
{
DPRINT1("Delete the Local DC structure\n");
LocalFree( pLDC );
}
}
#endif
Ret = NtGdiDeleteObjectApp(hDC);
return Ret;
}
/*
* @implemented
*/
BOOL
STDCALL
DeleteObject(HGDIOBJ hObject)
{
/* From Wine: DeleteObject does not SetLastError() on a null object */
if(!hObject) return FALSE;
if (0 != ((DWORD) hObject & GDI_HANDLE_STOCK_MASK))
{
DPRINT1("Trying to delete system object 0x%x\n", hObject);
return TRUE;
}
/* deleting a handle that doesn't belong to the caller should be rather rarely
so for the sake of speed just try to delete it without checking validity */
return NtGdiDeleteObject(hObject);
}
INT
STDCALL
GetArcDirection( HDC hdc )
{
return GetDCDWord( hdc, GdiGetArcDirection, 0);
}
INT
STDCALL
SetArcDirection( HDC hdc, INT nDirection )
{
return GetAndSetDCDWord( hdc, GdiGetSetArcDirection, nDirection, 0, 0, 0 );
}
/*
* @implemented
*/
DWORD
STDCALL
GetRelAbs(
HDC hdc,
DWORD dwIgnore
)
{
return GetDCDWord( hdc, GdiGetRelAbs, 0);
}
/*
* @implemented
*/
DWORD
STDCALL
SetRelAbs(
HDC hdc,
INT Mode
)
{
return GetAndSetDCDWord( hdc, GdiGetSetRelAbs, Mode, 0, 0, 0 );
}
/*
* @implemented
*/
DWORD
STDCALL
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
STDCALL
GetDCDWord( HDC hDC, INT u, DWORD Result )
{
BOOL Ret = NtGdiGetDCDword( hDC, u, (DWORD*) &u );
if (!Ret) return Result;
else return u;
}
BOOL
STDCALL
GetAspectRatioFilterEx(
HDC hdc,
LPSIZE lpAspectRatio
)
{
return NtGdiGetDCPoint( hdc, GdiGetAspectRatioFilter, (LPPOINT) lpAspectRatio );
}
/*
* @implemented
*/
BOOL
STDCALL
GetDCOrgEx(
HDC hdc,
LPPOINT lpPoint
)
{
return NtGdiGetDCPoint( hdc, GdiGetDCOrg, lpPoint );
}
/*
* @implemented
*/
LONG
STDCALL
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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -