Alexandre Julliard : user32: Reimplement 16-bit clipboard functions on top of the 32-bit ones.
Alexandre Julliard
julliard at winehq.org
Wed Dec 23 10:04:14 CST 2009
Module: wine
Branch: master
Commit: 3313c40b7ca745b3500cd48b51bb0d8d2fd3da98
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3313c40b7ca745b3500cd48b51bb0d8d2fd3da98
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Dec 22 21:08:11 2009 +0100
user32: Reimplement 16-bit clipboard functions on top of the 32-bit ones.
---
dlls/user32/clipboard.c | 51 -------------
dlls/user32/user16.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 190 insertions(+), 53 deletions(-)
diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c
index 860e73f..e399704 100644
--- a/dlls/user32/clipboard.c
+++ b/dlls/user32/clipboard.c
@@ -461,35 +461,6 @@ BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext)
/**************************************************************************
- * SetClipboardData (USER.141)
- */
-HANDLE16 WINAPI SetClipboardData16(UINT16 wFormat, HANDLE16 hData)
-{
- CLIPBOARDINFO cbinfo;
- HANDLE16 hResult = 0;
-
- TRACE("(%04X, %04x) !\n", wFormat, hData);
-
- /* If it's not owned, data can only be set if the format doesn't exists
- and its rendering is not delayed */
- if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
- (!(cbinfo.flags & CB_OWNER) && !hData))
- {
- WARN("Clipboard not owned by calling task. Operation failed.\n");
- return 0;
- }
-
- if (USER_Driver->pSetClipboardData(wFormat, hData, 0, cbinfo.flags & CB_OWNER))
- {
- hResult = hData;
- bCBHasChanged = TRUE;
- }
-
- return hResult;
-}
-
-
-/**************************************************************************
* SetClipboardData (USER32.@)
*/
HANDLE WINAPI SetClipboardData(UINT wFormat, HANDLE hData)
@@ -561,28 +532,6 @@ BOOL WINAPI IsClipboardFormatAvailable(UINT wFormat)
/**************************************************************************
- * GetClipboardData (USER.142)
- */
-HANDLE16 WINAPI GetClipboardData16(UINT16 wFormat)
-{
- HANDLE16 hData = 0;
- CLIPBOARDINFO cbinfo;
-
- if (!CLIPBOARD_GetClipboardInfo(&cbinfo) ||
- (~cbinfo.flags & CB_OPEN))
- {
- WARN("Clipboard not opened by calling task.\n");
- SetLastError(ERROR_CLIPBOARD_NOT_OPEN);
- return 0;
- }
-
- if (!USER_Driver->pGetClipboardData(wFormat, &hData, NULL)) hData = 0;
-
- return hData;
-}
-
-
-/**************************************************************************
* GetClipboardData (USER32.@)
*/
HANDLE WINAPI GetClipboardData(UINT wFormat)
diff --git a/dlls/user32/user16.c b/dlls/user32/user16.c
index fc2f2e8..51240a1 100644
--- a/dlls/user32/user16.c
+++ b/dlls/user32/user16.c
@@ -40,9 +40,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(user);
/* handle to handle 16 conversions */
#define HANDLE_16(h32) (LOWORD(h32))
+#define HGDIOBJ_16(h32) (LOWORD(h32))
/* handle16 to handle conversions */
#define HANDLE_32(h16) ((HANDLE)(ULONG_PTR)(h16))
+#define HGDIOBJ_32(h16) ((HGDIOBJ)(ULONG_PTR)(h16))
#define HINSTANCE_32(h16) ((HINSTANCE)(ULONG_PTR)(h16))
#define IS_MENU_STRING_ITEM(flags) \
@@ -340,6 +342,52 @@ static void free_module_icons( HINSTANCE16 inst )
}
}
+/**********************************************************************
+ * Management of the 16-bit clipboard formats
+ */
+
+struct clipboard_format
+{
+ struct list entry;
+ UINT format;
+ HANDLE16 data;
+};
+
+static struct list clipboard_formats = LIST_INIT( clipboard_formats );
+
+static void set_clipboard_format( UINT format, HANDLE16 data )
+{
+ struct clipboard_format *fmt;
+
+ /* replace it if it exists already */
+ LIST_FOR_EACH_ENTRY( fmt, &clipboard_formats, struct clipboard_format, entry )
+ {
+ if (fmt->format != format) continue;
+ GlobalFree16( fmt->data );
+ fmt->data = data;
+ return;
+ }
+
+ if ((fmt = HeapAlloc( GetProcessHeap(), 0, sizeof(*fmt) )))
+ {
+ fmt->format = format;
+ fmt->data = data;
+ list_add_tail( &clipboard_formats, &fmt->entry );
+ }
+}
+
+static void free_clipboard_formats(void)
+{
+ struct list *head;
+
+ while ((head = list_head( &clipboard_formats )))
+ {
+ struct clipboard_format *fmt = LIST_ENTRY( head, struct clipboard_format, entry );
+ list_remove( &fmt->entry );
+ GlobalFree16( fmt->data );
+ HeapFree( GetProcessHeap(), 0, fmt );
+ }
+}
/**********************************************************************
* InitApp (USER.5)
@@ -679,7 +727,9 @@ void WINAPI MessageBeep16( UINT16 i )
*/
BOOL16 WINAPI CloseClipboard16(void)
{
- return CloseClipboard();
+ BOOL ret = CloseClipboard();
+ if (ret) free_clipboard_formats();
+ return ret;
}
@@ -688,7 +738,145 @@ BOOL16 WINAPI CloseClipboard16(void)
*/
BOOL16 WINAPI EmptyClipboard16(void)
{
- return EmptyClipboard();
+ BOOL ret = EmptyClipboard();
+ if (ret) free_clipboard_formats();
+ return ret;
+}
+
+
+/**************************************************************************
+ * SetClipboardData (USER.141)
+ */
+HANDLE16 WINAPI SetClipboardData16( UINT16 format, HANDLE16 data16 )
+{
+ HANDLE data32 = 0;
+
+ switch (format)
+ {
+ case CF_BITMAP:
+ case CF_PALETTE:
+ data32 = HGDIOBJ_32( data16 );
+ break;
+
+ case CF_METAFILEPICT:
+ {
+ METAHEADER *header;
+ METAFILEPICT *pict32;
+ METAFILEPICT16 *pict16 = GlobalLock16( data16 );
+
+ if (pict16)
+ {
+ if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, sizeof(*pict32) ))) return 0;
+ pict32 = GlobalLock( data32 );
+ pict32->mm = pict16->mm;
+ pict32->xExt = pict16->xExt;
+ pict32->yExt = pict16->yExt;
+ header = GlobalLock16( pict16->hMF );
+ pict32->hMF = SetMetaFileBitsEx( header->mtSize * 2, (BYTE *)header );
+ GlobalUnlock16( pict16->hMF );
+ GlobalUnlock( data32 );
+ }
+ set_clipboard_format( format, data16 );
+ break;
+ }
+
+ case CF_ENHMETAFILE:
+ FIXME( "enhmetafile not supported in 16-bit\n" );
+ return 0;
+
+ default:
+ if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
+ data32 = HGDIOBJ_32( data16 );
+ else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
+ data32 = HANDLE_32( data16 );
+ else
+ {
+ UINT size = GlobalSize16( data16 );
+ void *ptr32, *ptr16 = GlobalLock16( data16 );
+ if (ptr16)
+ {
+ if (!(data32 = GlobalAlloc( GMEM_MOVEABLE, size ))) return 0;
+ ptr32 = GlobalLock( data32 );
+ memcpy( ptr32, ptr16, size );
+ GlobalUnlock( data32 );
+ }
+ set_clipboard_format( format, data16 );
+ }
+ break;
+ }
+
+ if (!SetClipboardData( format, data32 )) return 0;
+ return data16;
+}
+
+
+/**************************************************************************
+ * GetClipboardData (USER.142)
+ */
+HANDLE16 WINAPI GetClipboardData16( UINT16 format )
+{
+ HANDLE data32 = GetClipboardData( format );
+ HANDLE16 data16 = 0;
+ UINT size;
+ void *ptr;
+
+ if (!data32) return 0;
+
+ switch (format)
+ {
+ case CF_BITMAP:
+ case CF_PALETTE:
+ data16 = HGDIOBJ_16( data32 );
+ break;
+
+ case CF_METAFILEPICT:
+ {
+ METAFILEPICT16 *pict16;
+ METAFILEPICT *pict32 = GlobalLock( data32 );
+
+ if (pict32)
+ {
+ if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, sizeof(*pict16) ))) return 0;
+ pict16 = GlobalLock16( data16 );
+ pict16->mm = pict32->mm;
+ pict16->xExt = pict32->xExt;
+ pict16->yExt = pict32->yExt;
+ size = GetMetaFileBitsEx( pict32->hMF, 0, NULL );
+ pict16->hMF = GlobalAlloc16( GMEM_MOVEABLE, size );
+ ptr = GlobalLock16( pict16->hMF );
+ GetMetaFileBitsEx( pict32->hMF, size, ptr );
+ GlobalUnlock16( pict16->hMF );
+ GlobalUnlock16( data16 );
+ set_clipboard_format( format, data16 );
+ }
+ break;
+ }
+
+ case CF_ENHMETAFILE:
+ FIXME( "enhmetafile not supported in 16-bit\n" );
+ return 0;
+
+ default:
+ if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
+ data16 = HGDIOBJ_16( data32 );
+ else if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
+ data16 = HANDLE_16( data32 );
+ else
+ {
+ void *ptr16, *ptr32 = GlobalLock( data32 );
+ if (ptr32)
+ {
+ size = GlobalSize( data32 );
+ if (!(data16 = GlobalAlloc16( GMEM_MOVEABLE, size ))) return 0;
+ ptr16 = GlobalLock16( data16 );
+ memcpy( ptr16, ptr32, size );
+ GlobalUnlock16( data16 );
+ set_clipboard_format( format, data16 );
+ }
+ }
+ break;
+ }
+ return data16;
}
More information about the wine-cvs
mailing list