gdi: Win16/32 split of most of the metafile support.
diff --git a/dlls/gdi/Makefile.in b/dlls/gdi/Makefile.in
index 50240d5..0086e67 100644
--- a/dlls/gdi/Makefile.in
+++ b/dlls/gdi/Makefile.in
@@ -56,6 +56,7 @@
dispdib.c \
env.c \
gdi16.c \
+ metafile16.c \
wing.c
RC_SRCS = version.rc
diff --git a/dlls/gdi/gdi_private.h b/dlls/gdi/gdi_private.h
index 7e06239..dc85d35 100644
--- a/dlls/gdi/gdi_private.h
+++ b/dlls/gdi/gdi_private.h
@@ -27,6 +27,8 @@
based metafile has mtType == 1 */
#define METAFILE_MEMORY 1
#define METAFILE_DISK 2
+#define MFHEADERSIZE (sizeof(METAHEADER))
+#define MFVERSION 0x300
typedef struct {
EMR emr;
@@ -395,6 +397,9 @@
extern HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh);
extern HMETAFILE16 MF_Create_HMETAFILE16(METAHEADER *mh);
extern METAHEADER *MF_CreateMetaHeaderDisk(METAHEADER *mr, LPCVOID filename, BOOL unicode );
+extern METAHEADER *MF_ReadMetaFile(HANDLE hfile);
+extern METAHEADER *MF_LoadDiskBasedMetaFile(METAHEADER *mh);
+extern BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh);
/* path.c */
diff --git a/dlls/gdi/metafile.c b/dlls/gdi/metafile.c
index 1219888..2af4df5 100644
--- a/dlls/gdi/metafile.c
+++ b/dlls/gdi/metafile.c
@@ -50,10 +50,7 @@
#include <string.h>
#include <fcntl.h>
-#include "wine/winbase16.h"
-#include "wine/wingdi16.h"
#include "gdi.h"
-#include "wownt32.h"
#include "winreg.h"
#include "winternl.h"
#include "gdi_private.h"
@@ -76,9 +73,6 @@
METAHEADER *mh;
} METAFILEOBJ;
-#define MFHEADERSIZE (sizeof(METAHEADER))
-#define MFVERSION 0x300
-
/******************************************************************
* MF_AddHandle
@@ -122,29 +116,6 @@
}
/******************************************************************
- * MF_Create_HMETATFILE16
- *
- * Creates a HMETAFILE16 object from a METAHEADER
- *
- * HMETAFILE16s are Global memory handles.
- */
-HMETAFILE16 MF_Create_HMETAFILE16(METAHEADER *mh)
-{
- HMETAFILE16 hmf;
- DWORD size = mh->mtSize * sizeof(WORD);
-
- hmf = GlobalAlloc16(GMEM_MOVEABLE, size);
- if(hmf)
- {
- METAHEADER *mh_dest = GlobalLock16(hmf);
- memcpy(mh_dest, mh, size);
- GlobalUnlock16(hmf);
- }
- HeapFree(GetProcessHeap(), 0, mh);
- return hmf;
-}
-
-/******************************************************************
* MF_GetMetaHeader
*
* Returns ptr to METAHEADER associated with HMETAFILE
@@ -162,28 +133,6 @@
}
/******************************************************************
- * MF_GetMetaHeader16
- *
- * Returns ptr to METAHEADER associated with HMETAFILE16
- * Should be followed by call to MF_ReleaseMetaHeader16
- */
-static METAHEADER *MF_GetMetaHeader16( HMETAFILE16 hmf )
-{
- return GlobalLock16(hmf);
-}
-
-/******************************************************************
- * MF_ReleaseMetaHeader16
- *
- * Releases METAHEADER associated with HMETAFILE16
- */
-static BOOL16 MF_ReleaseMetaHeader16( HMETAFILE16 hmf )
-{
- return GlobalUnlock16( hmf );
-}
-
-
-/******************************************************************
* convert_points
*
* Convert an array of POINT16 to an array of POINT.
@@ -204,15 +153,6 @@
return ret;
}
-
-/******************************************************************
- * DeleteMetaFile (GDI.127)
- */
-BOOL16 WINAPI DeleteMetaFile16( HMETAFILE16 hmf )
-{
- return !GlobalFree16( hmf );
-}
-
/******************************************************************
* DeleteMetaFile (GDI32.@)
*
@@ -234,7 +174,7 @@
* Returns a pointer to a memory based METAHEADER read in from file HFILE
*
*/
-static METAHEADER *MF_ReadMetaFile(HANDLE hfile)
+METAHEADER *MF_ReadMetaFile(HANDLE hfile)
{
METAHEADER *mh;
DWORD BytesRead, size;
@@ -272,29 +212,6 @@
}
/******************************************************************
- * GetMetaFile (GDI.124)
- */
-HMETAFILE16 WINAPI GetMetaFile16( LPCSTR lpFilename )
-{
- METAHEADER *mh;
- HANDLE hFile;
-
- TRACE("%s\n", lpFilename);
-
- if(!lpFilename)
- return 0;
-
- if((hFile = CreateFileA(lpFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
- OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
- return 0;
-
- mh = MF_ReadMetaFile(hFile);
- CloseHandle(hFile);
- if(!mh) return 0;
- return MF_Create_HMETAFILE16( mh );
-}
-
-/******************************************************************
* GetMetaFileA (GDI32.@)
*
* Read a metafile from a file. Returns handle to a memory-based metafile.
@@ -319,8 +236,6 @@
return MF_Create_HMETAFILE( mh );
}
-
-
/******************************************************************
* GetMetaFileW (GDI32.@)
*/
@@ -350,7 +265,7 @@
*
* Creates a new memory-based metafile from a disk-based one.
*/
-static METAHEADER *MF_LoadDiskBasedMetaFile(METAHEADER *mh)
+METAHEADER *MF_LoadDiskBasedMetaFile(METAHEADER *mh)
{
METAHEADERDISK *mhd;
HANDLE hfile;
@@ -396,43 +311,6 @@
}
/******************************************************************
- * CopyMetaFile (GDI.151)
- */
-HMETAFILE16 WINAPI CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename)
-{
- METAHEADER *mh = MF_GetMetaHeader16( hSrcMetaFile );
- METAHEADER *mh2 = NULL;
- HANDLE hFile;
-
- TRACE("(%08x,%s)\n", hSrcMetaFile, lpFilename);
-
- if(!mh) return 0;
-
- if(mh->mtType == METAFILE_DISK)
- mh2 = MF_LoadDiskBasedMetaFile(mh);
- else {
- mh2 = HeapAlloc( GetProcessHeap(), 0, mh->mtSize * 2 );
- memcpy( mh2, mh, mh->mtSize * 2 );
- }
- MF_ReleaseMetaHeader16( hSrcMetaFile );
-
- if(lpFilename) { /* disk based metafile */
- DWORD w;
- if((hFile = CreateFileA(lpFilename, GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
- HeapFree( GetProcessHeap(), 0, mh2 );
- return 0;
- }
- WriteFile(hFile, mh2, mh2->mtSize * 2, &w, NULL);
- CloseHandle(hFile);
- mh2 = MF_CreateMetaHeaderDisk(mh2, lpFilename, FALSE);
- }
-
- return MF_Create_HMETAFILE16( mh2 );
-}
-
-
-/******************************************************************
* CopyMetaFileW (GDI32.@)
*
* Copies the metafile corresponding to hSrcMetaFile to either
@@ -500,43 +378,12 @@
return ret;
}
-
-/******************************************************************
- * IsValidMetaFile (GDI.410)
- *
- * Attempts to check if a given metafile is correctly formatted.
- * Currently, the only things verified are several properties of the
- * header.
- *
- * RETURNS
- * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
- *
- * BUGS
- * This is not exactly what windows does, see _Undocumented_Windows_
- * for details.
- */
-BOOL16 WINAPI IsValidMetaFile16(HMETAFILE16 hmf)
-{
- BOOL16 res=FALSE;
- METAHEADER *mh = MF_GetMetaHeader16(hmf);
- if (mh) {
- if (mh->mtType == METAFILE_MEMORY || mh->mtType == METAFILE_DISK)
- if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
- if (mh->mtVersion == MFVERSION)
- res=TRUE;
- MF_ReleaseMetaHeader16(hmf);
- }
- TRACE("IsValidMetaFile %x => %d\n",hmf,res);
- return res;
-}
-
-
/*******************************************************************
* MF_PlayMetaFile
*
* Helper for PlayMetaFile
*/
-static BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh)
+BOOL MF_PlayMetaFile( HDC hdc, METAHEADER *mh)
{
METARECORD *mr;
@@ -599,19 +446,6 @@
}
/******************************************************************
- * PlayMetaFile (GDI.123)
- *
- */
-BOOL16 WINAPI PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
-{
- BOOL16 ret;
- METAHEADER *mh = MF_GetMetaHeader16( hmf );
- ret = MF_PlayMetaFile( HDC_32(hdc), mh );
- MF_ReleaseMetaHeader16( hmf );
- return ret;
-}
-
-/******************************************************************
* PlayMetaFile (GDI32.@)
*
* Renders the metafile specified by hmf in the DC specified by
@@ -631,99 +465,6 @@
return MF_PlayMetaFile( hdc, mh );
}
-
-/******************************************************************
- * EnumMetaFile (GDI.175)
- *
- */
-BOOL16 WINAPI EnumMetaFile16( HDC16 hdc16, HMETAFILE16 hmf,
- MFENUMPROC16 lpEnumFunc, LPARAM lpData )
-{
- METAHEADER *mh = MF_GetMetaHeader16(hmf);
- METARECORD *mr;
- HANDLETABLE16 *ht;
- HDC hdc = HDC_32(hdc16);
- HGLOBAL16 hHT;
- SEGPTR spht;
- unsigned int offset = 0;
- WORD i, seg;
- HPEN hPen;
- HBRUSH hBrush;
- HFONT hFont;
- WORD args[8];
- BOOL16 result = TRUE, loaded = FALSE;
-
- TRACE("(%p, %04x, %p, %08lx)\n", hdc, hmf, lpEnumFunc, lpData);
-
- if(!mh) return FALSE;
- if(mh->mtType == METAFILE_DISK) { /* Create a memory-based copy */
- mh = MF_LoadDiskBasedMetaFile(mh);
- if(!mh) return FALSE;
- loaded = TRUE;
- }
-
- /* save the current pen, brush and font */
- hPen = GetCurrentObject(hdc, OBJ_PEN);
- hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
- hFont = GetCurrentObject(hdc, OBJ_FONT);
-
- /* create the handle table */
-
- hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
- sizeof(HANDLETABLE16) * mh->mtNoObjects);
- spht = WOWGlobalLock16(hHT);
-
- seg = hmf | 7;
- offset = mh->mtHeaderSize * 2;
-
- /* loop through metafile records */
-
- args[7] = hdc16;
- args[6] = SELECTOROF(spht);
- args[5] = OFFSETOF(spht);
- args[4] = seg + (HIWORD(offset) << __AHSHIFT);
- args[3] = LOWORD(offset);
- args[2] = mh->mtNoObjects;
- args[1] = HIWORD(lpData);
- args[0] = LOWORD(lpData);
-
- while (offset < (mh->mtSize * 2))
- {
- DWORD ret;
-
- mr = (METARECORD *)((char *)mh + offset);
-
- WOWCallback16Ex( (DWORD)lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &ret );
- if (!LOWORD(ret))
- {
- result = FALSE;
- break;
- }
-
- offset += (mr->rdSize * 2);
- args[4] = seg + (HIWORD(offset) << __AHSHIFT);
- args[3] = LOWORD(offset);
- }
-
- SelectObject(hdc, hBrush);
- SelectObject(hdc, hPen);
- SelectObject(hdc, hFont);
-
- ht = (HANDLETABLE16 *)GlobalLock16(hHT);
-
- /* free objects in handle table */
- for(i = 0; i < mh->mtNoObjects; i++)
- if(*(ht->objectHandle + i) != 0)
- DeleteObject( (HGDIOBJ)(ULONG_PTR)(*(ht->objectHandle + i) ));
-
- /* free handle table */
- GlobalFree16(hHT);
- if(loaded)
- HeapFree( GetProcessHeap(), 0, mh );
- MF_ReleaseMetaHeader16(hmf);
- return result;
-}
-
/******************************************************************
* EnumMetaFile (GDI32.@)
*
@@ -1305,60 +1046,6 @@
}
/******************************************************************
- * GetMetaFileBits (GDI.159)
- *
- * Trade in a metafile object handle for a handle to the metafile memory.
- *
- * PARAMS
- * hmf [I] metafile handle
- */
-
-HGLOBAL16 WINAPI GetMetaFileBits16( HMETAFILE16 hmf )
-{
- TRACE("hMem out: %04x\n", hmf);
- return hmf;
-}
-
-/******************************************************************
- * SetMetaFileBits (GDI.160)
- *
- * Trade in a metafile memory handle for a handle to a metafile object.
- * The memory region should hold a proper metafile, otherwise
- * problems will occur when it is used. Validity of the memory is not
- * checked. The function is essentially just the identity function.
- *
- * PARAMS
- * hMem [I] handle to a memory region holding a metafile
- *
- * RETURNS
- * Handle to a metafile on success, NULL on failure..
- */
-HMETAFILE16 WINAPI SetMetaFileBits16( HGLOBAL16 hMem )
-{
- TRACE("hmf out: %04x\n", hMem);
-
- return hMem;
-}
-
-/******************************************************************
- * SetMetaFileBitsBetter (GDI.196)
- *
- * Trade in a metafile memory handle for a handle to a metafile object,
- * making a cursory check (using IsValidMetaFile()) that the memory
- * handle points to a valid metafile.
- *
- * RETURNS
- * Handle to a metafile on success, NULL on failure..
- */
-HMETAFILE16 WINAPI SetMetaFileBitsBetter16( HMETAFILE16 hMeta )
-{
- if( IsValidMetaFile16( hMeta ) )
- return (HMETAFILE16)GlobalReAlloc16( hMeta, 0,
- GMEM_SHARE | GMEM_NODISCARD | GMEM_MODIFY);
- return (HMETAFILE16)0;
-}
-
-/******************************************************************
* SetMetaFileBitsEx (GDI32.@)
*
* Create a metafile from raw data. No checking of the data is performed.
diff --git a/dlls/gdi/metafile16.c b/dlls/gdi/metafile16.c
new file mode 100644
index 0000000..068b9d6
--- /dev/null
+++ b/dlls/gdi/metafile16.c
@@ -0,0 +1,316 @@
+/*
+ * Metafile functions
+ *
+ * Copyright David W. Metcalfe, 1994
+ * Copyright Niels de Carpentier, 1996
+ * Copyright Albrecht Kleine, 1996
+ * Copyright Huw Davies, 1996
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <fcntl.h>
+
+#include "wine/winbase16.h"
+#include "wine/wingdi16.h"
+#include "gdi.h"
+#include "wownt32.h"
+#include "winreg.h"
+#include "winternl.h"
+#include "gdi_private.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(metafile);
+
+/******************************************************************
+ * MF_GetMetaHeader16
+ *
+ * Returns ptr to METAHEADER associated with HMETAFILE16
+ * Should be followed by call to MF_ReleaseMetaHeader16
+ */
+static METAHEADER *MF_GetMetaHeader16( HMETAFILE16 hmf )
+{
+ return GlobalLock16(hmf);
+}
+
+/******************************************************************
+ * MF_ReleaseMetaHeader16
+ *
+ * Releases METAHEADER associated with HMETAFILE16
+ */
+static BOOL16 MF_ReleaseMetaHeader16( HMETAFILE16 hmf )
+{
+ return GlobalUnlock16( hmf );
+}
+
+/******************************************************************
+ * DeleteMetaFile (GDI.127)
+ */
+BOOL16 WINAPI DeleteMetaFile16( HMETAFILE16 hmf )
+{
+ return !GlobalFree16( hmf );
+}
+
+/******************************************************************
+ * GetMetaFile (GDI.124)
+ */
+HMETAFILE16 WINAPI GetMetaFile16( LPCSTR lpFilename )
+{
+ METAHEADER *mh;
+ HANDLE hFile;
+
+ TRACE("%s\n", lpFilename);
+
+ if(!lpFilename)
+ return 0;
+
+ if((hFile = CreateFileA(lpFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE)
+ return 0;
+
+ mh = MF_ReadMetaFile(hFile);
+ CloseHandle(hFile);
+ if(!mh) return 0;
+ return MF_Create_HMETAFILE16( mh );
+}
+
+/******************************************************************
+ * CopyMetaFile (GDI.151)
+ */
+HMETAFILE16 WINAPI CopyMetaFile16( HMETAFILE16 hSrcMetaFile, LPCSTR lpFilename)
+{
+ METAHEADER *mh = MF_GetMetaHeader16( hSrcMetaFile );
+ METAHEADER *mh2 = NULL;
+ HANDLE hFile;
+
+ TRACE("(%08x,%s)\n", hSrcMetaFile, lpFilename);
+
+ if(!mh) return 0;
+
+ if(mh->mtType == METAFILE_DISK)
+ mh2 = MF_LoadDiskBasedMetaFile(mh);
+ else {
+ mh2 = HeapAlloc( GetProcessHeap(), 0, mh->mtSize * 2 );
+ memcpy( mh2, mh, mh->mtSize * 2 );
+ }
+ MF_ReleaseMetaHeader16( hSrcMetaFile );
+
+ if(lpFilename) { /* disk based metafile */
+ DWORD w;
+ if((hFile = CreateFileA(lpFilename, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) {
+ HeapFree( GetProcessHeap(), 0, mh2 );
+ return 0;
+ }
+ WriteFile(hFile, mh2, mh2->mtSize * 2, &w, NULL);
+ CloseHandle(hFile);
+ mh2 = MF_CreateMetaHeaderDisk(mh2, lpFilename, FALSE);
+ }
+
+ return MF_Create_HMETAFILE16( mh2 );
+}
+
+/******************************************************************
+ * IsValidMetaFile (GDI.410)
+ *
+ * Attempts to check if a given metafile is correctly formatted.
+ * Currently, the only things verified are several properties of the
+ * header.
+ *
+ * RETURNS
+ * TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
+ *
+ * BUGS
+ * This is not exactly what windows does, see _Undocumented_Windows_
+ * for details.
+ */
+BOOL16 WINAPI IsValidMetaFile16(HMETAFILE16 hmf)
+{
+ BOOL16 res=FALSE;
+ METAHEADER *mh = MF_GetMetaHeader16(hmf);
+ if (mh) {
+ if (mh->mtType == METAFILE_MEMORY || mh->mtType == METAFILE_DISK)
+ if (mh->mtHeaderSize == MFHEADERSIZE/sizeof(INT16))
+ if (mh->mtVersion == MFVERSION)
+ res=TRUE;
+ MF_ReleaseMetaHeader16(hmf);
+ }
+ TRACE("IsValidMetaFile %x => %d\n",hmf,res);
+ return res;
+}
+
+/******************************************************************
+ * PlayMetaFile (GDI.123)
+ *
+ */
+BOOL16 WINAPI PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
+{
+ BOOL16 ret;
+ METAHEADER *mh = MF_GetMetaHeader16( hmf );
+ ret = MF_PlayMetaFile( HDC_32(hdc), mh );
+ MF_ReleaseMetaHeader16( hmf );
+ return ret;
+}
+
+
+/******************************************************************
+ * EnumMetaFile (GDI.175)
+ *
+ */
+BOOL16 WINAPI EnumMetaFile16( HDC16 hdc16, HMETAFILE16 hmf,
+ MFENUMPROC16 lpEnumFunc, LPARAM lpData )
+{
+ METAHEADER *mh = MF_GetMetaHeader16(hmf);
+ METARECORD *mr;
+ HANDLETABLE16 *ht;
+ HDC hdc = HDC_32(hdc16);
+ HGLOBAL16 hHT;
+ SEGPTR spht;
+ unsigned int offset = 0;
+ WORD i, seg;
+ HPEN hPen;
+ HBRUSH hBrush;
+ HFONT hFont;
+ WORD args[8];
+ BOOL16 result = TRUE, loaded = FALSE;
+
+ TRACE("(%p, %04x, %p, %08lx)\n", hdc, hmf, lpEnumFunc, lpData);
+
+ if(!mh) return FALSE;
+ if(mh->mtType == METAFILE_DISK) { /* Create a memory-based copy */
+ mh = MF_LoadDiskBasedMetaFile(mh);
+ if(!mh) return FALSE;
+ loaded = TRUE;
+ }
+
+ /* save the current pen, brush and font */
+ hPen = GetCurrentObject(hdc, OBJ_PEN);
+ hBrush = GetCurrentObject(hdc, OBJ_BRUSH);
+ hFont = GetCurrentObject(hdc, OBJ_FONT);
+
+ /* create the handle table */
+
+ hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
+ sizeof(HANDLETABLE16) * mh->mtNoObjects);
+ spht = WOWGlobalLock16(hHT);
+
+ seg = hmf | 7;
+ offset = mh->mtHeaderSize * 2;
+
+ /* loop through metafile records */
+
+ args[7] = hdc16;
+ args[6] = SELECTOROF(spht);
+ args[5] = OFFSETOF(spht);
+ args[4] = seg + (HIWORD(offset) << __AHSHIFT);
+ args[3] = LOWORD(offset);
+ args[2] = mh->mtNoObjects;
+ args[1] = HIWORD(lpData);
+ args[0] = LOWORD(lpData);
+
+ while (offset < (mh->mtSize * 2))
+ {
+ DWORD ret;
+
+ mr = (METARECORD *)((char *)mh + offset);
+
+ WOWCallback16Ex( (DWORD)lpEnumFunc, WCB16_PASCAL, sizeof(args), args, &ret );
+ if (!LOWORD(ret))
+ {
+ result = FALSE;
+ break;
+ }
+
+ offset += (mr->rdSize * 2);
+ args[4] = seg + (HIWORD(offset) << __AHSHIFT);
+ args[3] = LOWORD(offset);
+ }
+
+ SelectObject(hdc, hBrush);
+ SelectObject(hdc, hPen);
+ SelectObject(hdc, hFont);
+
+ ht = (HANDLETABLE16 *)GlobalLock16(hHT);
+
+ /* free objects in handle table */
+ for(i = 0; i < mh->mtNoObjects; i++)
+ if(*(ht->objectHandle + i) != 0)
+ DeleteObject( (HGDIOBJ)(ULONG_PTR)(*(ht->objectHandle + i) ));
+
+ /* free handle table */
+ GlobalFree16(hHT);
+ if(loaded)
+ HeapFree( GetProcessHeap(), 0, mh );
+ MF_ReleaseMetaHeader16(hmf);
+ return result;
+}
+
+/******************************************************************
+ * GetMetaFileBits (GDI.159)
+ *
+ * Trade in a metafile object handle for a handle to the metafile memory.
+ *
+ * PARAMS
+ * hmf [I] metafile handle
+ */
+
+HGLOBAL16 WINAPI GetMetaFileBits16( HMETAFILE16 hmf )
+{
+ TRACE("hMem out: %04x\n", hmf);
+ return hmf;
+}
+
+/******************************************************************
+ * SetMetaFileBits (GDI.160)
+ *
+ * Trade in a metafile memory handle for a handle to a metafile object.
+ * The memory region should hold a proper metafile, otherwise
+ * problems will occur when it is used. Validity of the memory is not
+ * checked. The function is essentially just the identity function.
+ *
+ * PARAMS
+ * hMem [I] handle to a memory region holding a metafile
+ *
+ * RETURNS
+ * Handle to a metafile on success, NULL on failure..
+ */
+HMETAFILE16 WINAPI SetMetaFileBits16( HGLOBAL16 hMem )
+{
+ TRACE("hmf out: %04x\n", hMem);
+
+ return hMem;
+}
+
+/******************************************************************
+ * SetMetaFileBitsBetter (GDI.196)
+ *
+ * Trade in a metafile memory handle for a handle to a metafile object,
+ * making a cursory check (using IsValidMetaFile()) that the memory
+ * handle points to a valid metafile.
+ *
+ * RETURNS
+ * Handle to a metafile on success, NULL on failure..
+ */
+HMETAFILE16 WINAPI SetMetaFileBitsBetter16( HMETAFILE16 hMeta )
+{
+ if( IsValidMetaFile16( hMeta ) )
+ return (HMETAFILE16)GlobalReAlloc16( hMeta, 0,
+ GMEM_SHARE | GMEM_NODISCARD | GMEM_MODIFY);
+ return (HMETAFILE16)0;
+}
+
diff --git a/dlls/gdi/mfdrv/init.c b/dlls/gdi/mfdrv/init.c
index 02cf777..67bbb7c 100644
--- a/dlls/gdi/mfdrv/init.c
+++ b/dlls/gdi/mfdrv/init.c
@@ -342,6 +342,29 @@
}
/******************************************************************
+ * MF_Create_HMETATFILE16
+ *
+ * Creates a HMETAFILE16 object from a METAHEADER
+ *
+ * HMETAFILE16s are Global memory handles.
+ */
+HMETAFILE16 MF_Create_HMETAFILE16(METAHEADER *mh)
+{
+ HMETAFILE16 hmf;
+ DWORD size = mh->mtSize * sizeof(WORD);
+
+ hmf = GlobalAlloc16(GMEM_MOVEABLE, size);
+ if(hmf)
+ {
+ METAHEADER *mh_dest = GlobalLock16(hmf);
+ memcpy(mh_dest, mh, size);
+ GlobalUnlock16(hmf);
+ }
+ HeapFree(GetProcessHeap(), 0, mh);
+ return hmf;
+}
+
+/******************************************************************
* CloseMetaFile (GDI.126)
*
* PARAMS