From aa64d1177fb47d3f0ebafd85a6aed42efa85924b Mon Sep 17 00:00:00 2001 From: Magnus Olsen Date: Fri, 15 Sep 2006 23:24:04 +0000 Subject: [PATCH] Implement NtGdiCreateEnhMetaFile it is base on wine cvs 15/9-2006 version of CreateEnhMetaFileW in wine gdi32.dll Our are not complete it can not create the file. But we parseing now some NULL pointer test and some other test in winetest for gdi32. svn path=/trunk/; revision=24137 --- reactos/subsystems/win32/win32k/include/dc.h | 4 + .../win32/win32k/objects/metafile.c | 166 +++++++++++++++++- 2 files changed, 168 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index e1019f6de77..542a19de282 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -121,6 +121,10 @@ typedef struct _DC HPALETTE PalIndexed; WIN_DC_INFO w; + + HANDLE hFile; + LPENHMETAHEADER emh; + } DC, *PDC; typedef struct _GDIPOINTER /* should stay private to ENG */ diff --git a/reactos/subsystems/win32/win32k/objects/metafile.c b/reactos/subsystems/win32/win32k/objects/metafile.c index aa7e02f6f0a..9c832ba371e 100644 --- a/reactos/subsystems/win32/win32k/objects/metafile.c +++ b/reactos/subsystems/win32/win32k/objects/metafile.c @@ -64,10 +64,172 @@ NtGdiCreateEnhMetaFile(HDC hDCRef, CONST LPRECT Rect, LPCWSTR Description) { - UNIMPLEMENTED; - return 0; + PDC Dc; + HDC ret = NULL; + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + DWORD length = 0; + HDC tempHDC; + DWORD MemSize; + + tempHDC = hDCRef; + if (hDCRef == NULL) + { + /* FIXME ?? + * Shall we create hdc NtGdiHdcCompatible hdc ?? + */ + UNICODE_STRING DriverName; + RtlInitUnicodeString(&DriverName, L"DISPLAY"); + tempHDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE); + } + + + Dc = DC_LockDc(tempHDC); + if (Dc == NULL) + { + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + SetLastWin32Error(ERROR_INVALID_HANDLE); + return NULL; + } + + if(Description) + { + length = wcslen(Description); + length += wcslen(Description + length + 1); + length += 3; + length *= 2; + } + + MemSize = sizeof(ENHMETAHEADER) + (length + 3) / 4 * 4; + + if (!(Dc->emh = EngAllocMem(FL_ZERO_MEMORY, MemSize, 0))) + { + DC_UnlockDc(Dc); + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + SetLastWin32Error(ERROR_INVALID_HANDLE); + return NULL; + } + + Dc->emh->iType = EMR_HEADER; + Dc->emh->nSize = MemSize; + + Dc->emh->rclBounds.left = Dc->emh->rclBounds.top = 0; + Dc->emh->rclBounds.right = Dc->emh->rclBounds.bottom = -1; + + if(Rect) + { + Dc->emh->rclFrame.left = Rect->left; + Dc->emh->rclFrame.top = Rect->top; + Dc->emh->rclFrame.right = Rect->right; + Dc->emh->rclFrame.bottom = Rect->bottom; + } + else + { + /* Set this to {0,0 - -1,-1} and update it at the end */ + Dc->emh->rclFrame.left = Dc->emh->rclFrame.top = 0; + Dc->emh->rclFrame.right = Dc->emh->rclFrame.bottom = -1; + } + + Dc->emh->dSignature = ENHMETA_SIGNATURE; + Dc->emh->nVersion = 0x10000; + Dc->emh->nBytes = Dc->emh->nSize; + Dc->emh->nRecords = 1; + Dc->emh->nHandles = 1; + + Dc->emh->sReserved = 0; /* According to docs, this is reserved and must be 0 */ + Dc->emh->nDescription = length / 2; + + Dc->emh->offDescription = length ? sizeof(ENHMETAHEADER) : 0; + + Dc->emh->nPalEntries = 0; /* I guess this should start at 0 */ + + /* Size in pixels */ + Dc->emh->szlDevice.cx = NtGdiGetDeviceCaps(tempHDC, HORZRES); + Dc->emh->szlDevice.cy = NtGdiGetDeviceCaps(tempHDC, VERTRES); + + /* Size in millimeters */ + Dc->emh->szlMillimeters.cx = NtGdiGetDeviceCaps(tempHDC, HORZSIZE); + Dc->emh->szlMillimeters.cy = NtGdiGetDeviceCaps(tempHDC, VERTSIZE); + + /* Size in micrometers */ + Dc->emh->szlMicrometers.cx = Dc->emh->szlMillimeters.cx * 1000; + Dc->emh->szlMicrometers.cy = Dc->emh->szlMillimeters.cy * 1000; + + if(Description) + { + memcpy((char *)Dc->emh + sizeof(ENHMETAHEADER), Description, length); + } + + ret = tempHDC; + + DPRINT1("File cretae unimplement in NtGdiCreateEnhMetaFile\n"); + if (File) + { + + + + /* disk based metafile */ + + /* FIXME + if ((Dc->hFile = CreateFileW(File, GENERIC_WRITE | GENERIC_READ, 0, + NULL, CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) + { + DC_UnLockDc(Dc); + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + return 0; + } + */ + + Status = NtWriteFile(Dc->hFile, NULL, NULL, NULL, &Iosb, (PVOID)&Dc->emh, Dc->emh->nSize, NULL, NULL); + if (Status == STATUS_PENDING) + { + Status = NtWaitForSingleObject(Dc->hFile,FALSE,NULL); + if (NT_SUCCESS(Status)) + { + Status = Iosb.Status; + } + } + + if (NT_SUCCESS(Status)) + { + //ret = Dc->hSelf; + ret = tempHDC; + DC_UnlockDc(Dc); + } + else + { + Dc->hFile = NULL; + /* FIXME use SetLastErrorByStatus */ + //SetLastErrorByStatus(Status); + SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); + ret = NULL; + DC_UnlockDc(Dc); + if (hDCRef == NULL) + { + NtGdiDeleteObjectApp(tempHDC); + } + } + } + else + { + DC_UnlockDc(Dc); + } + + return ret; } + + + HDC STDCALL NtGdiCreateMetaFile(LPCWSTR File)