Module: wine Branch: master Commit: 3313c40b7ca745b3500cd48b51bb0d8d2fd3da98 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3313c40b7ca745b3500cd48b51...
Author: Alexandre Julliard julliard@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; }