}
/*
- * @unimplemented
+ * @implemented
*/
-HENHMETAFILE
+HANDLE
WINAPI
-GdiConvertEnhMetaFile(HENHMETAFILE hmf)
+GdiConvertEnhMetaFile(HENHMETAFILE hemf)
{
- UNIMPLEMENTED;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ HANDLE hmo = NULL;
+ BYTE * Buffer = NULL;
+ UINT nSize;
+
+ nSize = GetEnhMetaFileBits( hemf, 0, NULL );
+ if (nSize == 0)
+ goto Exit;
+
+ // allocate buffer
+ Buffer = (BYTE *)LocalAlloc(LPTR, nSize);
+ if (Buffer == NULL)
+ goto Exit;
+
+ nSize = GetEnhMetaFileBits( hemf, nSize, Buffer );
+ if (nSize == 0)
+ goto Exit;
+
+ hmo = NtGdiCreateServerMetaFile( GDITAG_TYPE_EMF, nSize, Buffer, 0, 0, 0 );
+
+Exit:
+ // clean up
+ if (Buffer)
+ LocalFree(Buffer);
+ return hmo;
}
/*
- * @unimplemented
+ * @implemented
*/
HENHMETAFILE
WINAPI
-GdiCreateLocalEnhMetaFile(HENHMETAFILE hmo)
+GdiCreateLocalEnhMetaFile(HANDLE hmo)
{
- UNIMPLEMENTED;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ HENHMETAFILE hEMF;
+ BYTE * Buffer = NULL;
+ UINT nSize;
+ DWORD iType, mm, xExt, yExt;
+
+ nSize = NtGdiGetServerMetaFileBits( hmo, 0, NULL, NULL, NULL, NULL, NULL);
+ if (nSize == 0)
+ goto Exit;
+
+ // allocate buffer
+ Buffer = (BYTE *)LocalAlloc(LPTR, nSize);
+ if (Buffer == NULL)
+ goto Exit;
+
+ // store to buffer
+ nSize = NtGdiGetServerMetaFileBits( hmo, nSize, Buffer, &iType, &mm, &xExt, &yExt);
+ if (nSize == 0)
+ goto Exit;
+
+ if ( iType == GDITAG_TYPE_MFP ) // handle conversion to EMF
+ {
+ METAFILEPICT Info;
+
+ Info.hMF = NULL;
+ Info.mm = mm;
+ Info.xExt = xExt;
+ Info.yExt = yExt;
+
+ hEMF = SetWinMetaFileBits( nSize, Buffer, NULL, &Info ); // Translate from old style to new style.
+ if (hEMF == NULL)
+ goto Exit;
+ }
+ else
+ {
+ hEMF = SetEnhMetaFileBits(nSize, Buffer);
+ if (hEMF == NULL)
+ goto Exit;
+ }
+
+Exit:
+ // clean up
+ if (Buffer)
+ LocalFree(Buffer);
+ return hEMF;
}
/*
* PROGRAMMERS: Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#include <precomp.h>
+
+#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
*/
HGLOBAL
WINAPI
-GdiCreateLocalMetaFilePict(HENHMETAFILE hEMF)
+GdiCreateLocalMetaFilePict(HANDLE hmo)
{
HGLOBAL hMetaFilePict;
METAFILEPICT * pInfo;
HMETAFILE hMF = NULL;
BYTE * Buffer = NULL;
+ BYTE * BufNew = NULL;
HDC hDC = NULL;
- UINT nSize;
+ UINT nSize, cSize;
+ DWORD iType;
// NOTE: On Win32, there is no difference between the local heap and
// the global heap. GlobalAlloc and LocalAlloc have same effect.
if (pInfo == NULL)
goto Exit;
- // create DC
- hDC = CreateCompatibleDC(NULL);
- if (hDC == NULL)
- goto Exit;
-
- // get size of dest buffer
- nSize = GetWinMetaFileBits(hEMF, 0, NULL, MM_ANISOTROPIC, hDC);
- if (nSize == 0)
- goto Exit;
+ nSize = NtGdiGetServerMetaFileBits( hmo, 0, NULL, NULL, NULL, NULL, NULL );
// allocate buffer
Buffer = (BYTE *)LocalAlloc(LPTR, nSize);
goto Exit;
// store to buffer
- nSize = GetWinMetaFileBits(hEMF, nSize, Buffer, MM_ANISOTROPIC, hDC);
+ nSize = NtGdiGetServerMetaFileBits( hmo, nSize, Buffer, &iType, (PDWORD)&pInfo->mm, (PDWORD)&pInfo->xExt, (PDWORD)&pInfo->yExt );
if (nSize == 0)
goto Exit;
+ if ( iType == GDITAG_TYPE_EMF ) // handle conversion to MFP
+ {
+ static const WCHAR szDisplayW[] = { 'D','I','S','P','L','A','Y','\0' };
+ HENHMETAFILE hEMF;
+ PENHMETAHEADER pemh = (PENHMETAHEADER)Buffer;
+
+ pInfo->mm = MM_ANISOTROPIC;
+ pInfo->xExt = pemh->rclFrame.right - pemh->rclFrame.left; // Width
+ pInfo->yExt = pemh->rclFrame.bottom - pemh->rclFrame.top; // Height
+
+ hEMF = SetEnhMetaFileBits(nSize, Buffer);
+ if (hEMF == NULL)
+ goto Exit;
+
+ hDC = CreateDCW(szDisplayW, NULL, NULL, NULL);
+ if (hDC)
+ {
+ cSize = GetWinMetaFileBits( hEMF, 0, NULL, MM_ANISOTROPIC, hDC );
+ if (cSize)
+ {
+ BufNew = (BYTE *)LocalAlloc(LPTR, cSize);
+ if (BufNew)
+ {
+ nSize = GetWinMetaFileBits( hEMF, cSize, (LPBYTE)BufNew, MM_ANISOTROPIC, hDC );
+ if (nSize == cSize)
+ {
+ if (Buffer) LocalFree(Buffer);
+ Buffer = BufNew;
+ }
+ }
+ }
+ DeleteDC(hDC);
+ }
+ DeleteEnhMetaFile(hEMF);
+
+ if (Buffer != BufNew)
+ goto Exit;
+ }
+
// create metafile from buffer
hMF = SetMetaFileBitsEx(nSize, Buffer);
if (hMF == NULL)
goto Exit;
- // no suggested size is supplied
- pInfo->mm = MM_ANISOTROPIC;
- pInfo->xExt = 0;
- pInfo->yExt = 0;
-
// set metafile handle
pInfo->hMF = hMF;
// clean up
if (Buffer)
LocalFree(Buffer);
- if (hDC)
- DeleteDC(hDC);
if (pInfo)
GlobalUnlock(hMetaFilePict);
if (hMF == NULL)
/*
* @implemented
*/
-HENHMETAFILE
+HANDLE
WINAPI
GdiConvertMetaFilePict(HGLOBAL hMetaFilePict)
{
HMETAFILE hMF;
UINT nSize;
- HENHMETAFILE hEMF = NULL;
- BYTE * Buffer = NULL;
- HDC hDC = NULL;
- METAFILEPICT * pInfo = NULL;
+ HANDLE hmo = NULL;
+ BYTE * Buffer = NULL;
+ METAFILEPICT * pInfo = NULL;
// get METAFILEPICT pointer
pInfo = (METAFILEPICT *)GlobalLock(hMetaFilePict);
// get metafile handle
hMF = pInfo->hMF;
- // Missing test for GDILoObjType_LO_METADC16_TYPE (hMF)
-
// get size of buffer
nSize = GetMetaFileBitsEx(hMF, 0, NULL);
if (nSize == 0)
if (nSize == 0)
goto Exit;
- // create DC
- hDC = CreateCompatibleDC(NULL);
- if (hDC == NULL)
- goto Exit;
-
- // create enhanced metafile from buffer
- hEMF = SetWinMetaFileBits(nSize, Buffer, hDC, pInfo);
+ hmo = NtGdiCreateServerMetaFile( GDITAG_TYPE_MFP, nSize, Buffer, pInfo->mm, pInfo->xExt, pInfo->yExt);
Exit:
// clean up
if (pInfo)
GlobalUnlock(hMetaFilePict);
- if (hDC)
- DeleteDC(hDC);
if (Buffer)
LocalFree(Buffer);
- return hEMF; // success if non-NULL
+ return hmo; // success if non-NULL
}
(objt) == GDIObjType_BRUSH_TYPE)
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt) \
ASSERT((objt) == GDIObjType_DC_TYPE || \
- (objt) == GDIObjType_RGN_TYPE)
+ (objt) == GDIObjType_RGN_TYPE || \
+ (objt) == GDIObjType_UMPD_TYPE || \
+ (objt) == GDIObjType_META_TYPE)
#define ASSERT_TRYLOCK_OBJECT_TYPE(objt) \
ASSERT((objt) == GDIObjType_DRVOBJ_TYPE)
#else
NULL, /* 12 GDIObjType_UNUSED4_TYPE */
NULL, /* 13 GDIObjType_SPACE_TYPE, unused */
NULL, /* 14 GDIObjType_UNUSED5_TYPE */
- NULL, /* 15 GDIObjType_META_TYPE, unused */
+ GDIOBJ_vCleanup, /* 15 GDIObjType_META_TYPE */
NULL, /* 16 GDIObjType_EFSTATE_TYPE, unused */
NULL, /* 17 GDIObjType_BMFD_TYPE, unused */
NULL, /* 18 GDIObjType_VTFD_TYPE, unused */
#define NDEBUG
#include <debug.h>
-// Need to move this to NtGdiTyp.h
-#define GDITAG_TYPE_EMF 'XEFM' // EnhMetaFile
-#define GDITAG_TYPE_MFP '_PFM' // MetaFile Picture
-// Internal Use
+// Internal Use Only
typedef struct _METATYPEOBJ
{
BASEOBJECT BaseObject;
} METATYPEOBJ, *PMETATYPEOBJ;
-//
-// Plug Me in Somewhere? Clipboard cleanup?
-//
-VOID
-FASTCALL
-METATYPEOBJ__vCleanup(PVOID ObjectBody)
-{
- PMETATYPEOBJ pmto = (PMETATYPEOBJ)ObjectBody;
- GDIOBJ_hInsertObject(&pmto->BaseObject, GDI_OBJ_HMGR_POWNED);
- GDIOBJ_vDeleteObject(&pmto->BaseObject);
-}
-
/* System Service Calls ******************************************************/
/*
cjData &&
pjData )
{
- pmto = (PMETATYPEOBJ)GDIOBJ_AllocObjWithHandle(GDIObjType_META_TYPE, sizeof(METATYPEOBJ) + cjData);
+ pmto = (PMETATYPEOBJ)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_META_TYPE, sizeof(METATYPEOBJ) + cjData);
if ( pmto )
{
pmto->iType = iType;
_SEH2_TRY
{
- ProbeForRead( pjData, cjData, 1 );
- RtlCopyMemory( pmto->pjData, pjData, cjData) ;
+ ProbeForRead( pjData, cjData, 1 );
+ RtlCopyMemory( pmto->pjData, pjData, cjData) ;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
if (Pass)
{
GDIOBJ_vSetObjectOwner(&pmto->BaseObject, GDI_OBJ_HMGR_PUBLIC);
- GDIOBJ_vDereferenceObject ((POBJ)pmto);
+ GDIOBJ_vUnlockObject(&pmto->BaseObject);
return pmto->BaseObject.hHmgr;
}
else
ULONG cjRet = 0;
PMETATYPEOBJ pmto;
- pmto = (PMETATYPEOBJ) GDIOBJ_ShareLockObj ((HGDIOBJ) hmo, GDIObjType_META_TYPE);
+ pmto = (PMETATYPEOBJ) GDIOBJ_LockObject( hmo, GDIObjType_META_TYPE);
if (!pmto)
return 0;
}
}
- GDIOBJ_vDereferenceObject ((POBJ)pmto);
+ GDIOBJ_vUnlockObject(&pmto->BaseObject);
return cjRet;
}
GDILoObjType_LO_REGION_TYPE = 0x40000,
GDILoObjType_LO_ICMLCS_TYPE = 0x90000,
GDILoObjType_LO_CLIENTOBJ_TYPE = 0x60000,
+ GDILoObjType_LO_UMPD_TYPE = 0x110000,
+ GDILoObjType_LO_META_TYPE = 0x150000,
GDILoObjType_LO_ALTDC_TYPE = 0x210000,
GDILoObjType_LO_PEN_TYPE = 0x300000,
GDILoObjType_LO_EXTPEN_TYPE = 0x500000,
/* Get/SetBounds/Rect support. */
#define DCB_WINDOWMGR 0x8000 /* Queries the Windows bounding rectangle instead of the application's */
+#define GDITAG_TYPE_EMF 'XEFM' // EnhMetaFile
+#define GDITAG_TYPE_MFP '_PFM' // MetaFile Picture
+
/* TYPES *********************************************************************/
typedef PVOID KERNEL_PVOID;
{
if (pElement->fGlobalHandle)
UserDeleteObject(pElement->hData, TYPE_CLIPDATA);
- else if (pElement->fmt == CF_BITMAP || pElement->fmt == CF_PALETTE ||
- pElement->fmt == CF_DSPBITMAP)
+ else if (pElement->fmt == CF_BITMAP ||
+ pElement->fmt == CF_PALETTE ||
+ pElement->fmt == CF_DSPBITMAP ||
+ pElement->fmt == CF_METAFILEPICT ||
+ pElement->fmt == CF_DSPMETAFILEPICT ||
+ pElement->fmt == CF_DSPENHMETAFILE ||
+ pElement->fmt == CF_ENHMETAFILE )
{
GreSetObjectOwner(pElement->hData, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(pElement->hData);
WINE_DEFAULT_DEBUG_CHANNEL(user32);
+HANDLE WINAPI GdiConvertMetaFilePict(HANDLE);
+HANDLE WINAPI GdiConvertEnhMetaFile(HANDLE);
+HANDLE WINAPI GdiCreateLocalEnhMetaFile(HANDLE);
+HANDLE WINAPI GdiCreateLocalMetaFilePict(HANDLE);
+
+
/*
* @implemented
*/
if (!hData)
return NULL;
+ switch (uFormat)
+ {
+ case CF_DSPMETAFILEPICT:
+ case CF_METAFILEPICT:
+ return GdiCreateLocalMetaFilePict(hData);
+ case CF_DSPENHMETAFILE:
+ case CF_ENHMETAFILE:
+ return GdiCreateLocalEnhMetaFile(hData);
+ }
+
if (gcd.fGlobalHandle)
{
HANDLE hGlobal;
else if (uFormat == CF_BITMAP || uFormat == CF_DSPBITMAP || uFormat == CF_PALETTE)
hRet = NtUserSetClipboardData(uFormat, hMem, &scd);
/* Meta files are probably checked for validity */
- else if (uFormat == CF_DSPMETAFILEPICT || uFormat == CF_METAFILEPICT ||
- uFormat == CF_DSPENHMETAFILE || uFormat == CF_ENHMETAFILE)
+ else if (uFormat == CF_DSPMETAFILEPICT || uFormat == CF_METAFILEPICT )
{
- UNIMPLEMENTED;
- hRet = NULL; // not supported yet
+ hMem = GdiConvertMetaFilePict( hMem );
+ hRet = NtUserSetClipboardData(uFormat, hMem, &scd);
+ }
+ else if (uFormat == CF_DSPENHMETAFILE || uFormat == CF_ENHMETAFILE)
+ {
+ hMem = GdiConvertEnhMetaFile( hMem );
+ hRet = NtUserSetClipboardData(uFormat, hMem, &scd);
}
else
{