Converted to the new debug interface, using script written by Patrik
[wine.git] / windows / clipboard.c
blobb64e169f9e584ea462b3d2464503091933370df3
1 /*
2 * WINE clipboard function handling
4 * Copyright 1994 Martin Ayotte
5 * 1996 Alex Korobka
7 */
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <string.h>
15 #include "winuser.h"
16 #include "wine/winuser16.h"
17 #include "heap.h"
18 #include "task.h"
19 #include "message.h"
20 #include "clipboard.h"
21 #include "xmalloc.h"
22 #include "debug.h"
24 DEFAULT_DEBUG_CHANNEL(clipboard)
26 #define CF_REGFORMATBASE 0xC000
28 /**************************************************************************
29 * internal variables
32 CLIPBOARD_DRIVER *CLIPBOARD_Driver = NULL;
34 static HQUEUE16 hqClipLock = 0;
35 static BOOL bCBHasChanged = FALSE;
37 HWND hWndClipOwner = 0; /* current clipboard owner */
38 HWND hWndClipWindow = 0; /* window that opened clipboard */
39 static HWND hWndViewer = 0; /* start of viewers chain */
41 static WORD LastRegFormat = CF_REGFORMATBASE;
43 WINE_CLIPFORMAT ClipFormats[16] = {
44 { CF_TEXT, 1, 0, "Text", (HANDLE)NULL, 0, NULL, &ClipFormats[1] , (HANDLE16)NULL},
45 { CF_BITMAP, 1, 0, "Bitmap", (HANDLE)NULL, 0, &ClipFormats[0], &ClipFormats[2] , (HANDLE16)NULL},
46 { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[1], &ClipFormats[3] , (HANDLE16)NULL},
47 { CF_SYLK, 1, 0, "Sylk", (HANDLE)NULL, 0, &ClipFormats[2], &ClipFormats[4] , (HANDLE16)NULL},
48 { CF_DIF, 1, 0, "DIF", (HANDLE)NULL, 0, &ClipFormats[3], &ClipFormats[5] , (HANDLE16)NULL},
49 { CF_TIFF, 1, 0, "TIFF", (HANDLE)NULL, 0, &ClipFormats[4], &ClipFormats[6] , (HANDLE16)NULL},
50 { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE)NULL, 0, &ClipFormats[5], &ClipFormats[7] , (HANDLE16)NULL},
51 { CF_DIB, 1, 0, "DIB", (HANDLE)NULL, 0, &ClipFormats[6], &ClipFormats[8] , (HANDLE16)NULL},
52 { CF_PALETTE, 1, 0, "Palette", (HANDLE)NULL, 0, &ClipFormats[7], &ClipFormats[9] , (HANDLE16)NULL},
53 { CF_PENDATA, 1, 0, "PenData", (HANDLE)NULL, 0, &ClipFormats[8], &ClipFormats[10] , (HANDLE16)NULL},
54 { CF_RIFF, 1, 0, "RIFF", (HANDLE)NULL, 0, &ClipFormats[9], &ClipFormats[11] , (HANDLE16)NULL},
55 { CF_WAVE, 1, 0, "Wave", (HANDLE)NULL, 0, &ClipFormats[10], &ClipFormats[12] , (HANDLE16)NULL},
56 { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE)NULL, 0, &ClipFormats[11], &ClipFormats[13] , (HANDLE16)NULL},
57 { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE)NULL, 0, &ClipFormats[12], &ClipFormats[14] , (HANDLE16)NULL},
58 { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[13], &ClipFormats[15] , (HANDLE16)NULL},
59 { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE)NULL, 0, &ClipFormats[14], NULL , (HANDLE16)NULL}
62 static LPWINE_CLIPFORMAT __lookup_format( LPWINE_CLIPFORMAT lpFormat, WORD wID )
64 while(TRUE)
66 if (lpFormat == NULL ||
67 lpFormat->wFormatID == wID) break;
68 lpFormat = lpFormat->NextFormat;
70 return lpFormat;
73 /**************************************************************************
74 * CLIPBOARD_ResetLock
76 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent, HQUEUE16 hqNew )
78 if( hqClipLock == hqCurrent )
80 if( hqNew )
81 hqClipLock = hqNew;
82 else
84 hWndClipOwner = 0;
85 hWndClipWindow = 0;
86 EmptyClipboard();
87 hqClipLock = 0;
93 /**************************************************************************
94 * CLIPBOARD_DeleteRecord
96 void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat, BOOL bChange)
98 if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
99 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP )
101 if (lpFormat->hData32)
102 DeleteObject(lpFormat->hData32);
103 if (lpFormat->hData16)
104 DeleteObject16(lpFormat->hData16);
106 else if( lpFormat->wFormatID == CF_METAFILEPICT )
108 if (lpFormat->hData32)
110 DeleteMetaFile( ((METAFILEPICT *)GlobalLock( lpFormat->hData32 ))->hMF );
111 GlobalFree(lpFormat->hData32);
112 if (lpFormat->hData16)
113 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
114 and a shallow copy is enough to share a METAFILEPICT
115 structure between 16bit and 32bit clipboards. The MetaFile
116 should of course only be deleted once. */
117 GlobalFree16(lpFormat->hData16);
119 else if (lpFormat->hData16)
121 DeleteMetaFile16( ((METAFILEPICT16 *)GlobalLock16( lpFormat->hData16 ))->hMF );
122 GlobalFree16(lpFormat->hData16);
125 else
127 if (lpFormat->hData32)
128 GlobalFree(lpFormat->hData32);
129 if (lpFormat->hData16)
130 GlobalFree16(lpFormat->hData16);
133 lpFormat->wDataPresent = 0;
134 lpFormat->hData16 = 0;
135 lpFormat->hData32 = 0;
137 if( bChange ) bCBHasChanged = TRUE;
140 /**************************************************************************
141 * CLIPBOARD_IsPresent
143 BOOL CLIPBOARD_IsPresent(WORD wFormat)
145 /* special case */
147 if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
148 return ClipFormats[CF_TEXT-1].wDataPresent ||
149 ClipFormats[CF_OEMTEXT-1].wDataPresent;
150 else
152 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
153 if( lpFormat ) return (lpFormat->wDataPresent);
155 return FALSE;
158 /**************************************************************************
159 * OpenClipboard16 (USER.137)
161 BOOL16 WINAPI OpenClipboard16( HWND16 hWnd )
163 return OpenClipboard( hWnd );
167 /**************************************************************************
168 * OpenClipboard32 (USER32.407)
170 * Note: Netscape uses NULL hWnd to open the clipboard.
172 BOOL WINAPI OpenClipboard( HWND hWnd )
174 BOOL bRet;
176 TRACE(clipboard,"(%04x)...\n", hWnd);
178 if (!hqClipLock)
180 hqClipLock = GetFastQueue16();
181 hWndClipWindow = hWnd;
182 bCBHasChanged = FALSE;
183 bRet = TRUE;
185 else bRet = FALSE;
187 TRACE(clipboard," returning %i\n", bRet);
188 return bRet;
192 /**************************************************************************
193 * CloseClipboard16 (USER.138)
195 BOOL16 WINAPI CloseClipboard16(void)
197 return CloseClipboard();
201 /**************************************************************************
202 * CloseClipboard32 (USER32.54)
204 BOOL WINAPI CloseClipboard(void)
206 TRACE(clipboard,"!\n");
208 if (hqClipLock == GetFastQueue16())
210 hWndClipWindow = 0;
212 if (bCBHasChanged && hWndViewer)
213 SendMessage16(hWndViewer, WM_DRAWCLIPBOARD, 0, 0L);
214 hqClipLock = 0;
216 return TRUE;
220 /**************************************************************************
221 * EmptyClipboard16 (USER.139)
223 BOOL16 WINAPI EmptyClipboard16(void)
225 return EmptyClipboard();
229 /**************************************************************************
230 * EmptyClipboard32 (USER32.169)
232 BOOL WINAPI EmptyClipboard(void)
234 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
236 TRACE(clipboard,"(void)\n");
238 if (hqClipLock != GetFastQueue16()) return FALSE;
240 /* destroy private objects */
242 if (hWndClipOwner)
243 SendMessage16(hWndClipOwner, WM_DESTROYCLIPBOARD, 0, 0L);
245 while(lpFormat)
247 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
248 CLIPBOARD_DeleteRecord( lpFormat, TRUE );
250 lpFormat = lpFormat->NextFormat;
253 hWndClipOwner = hWndClipWindow;
255 CLIPBOARD_Driver->pEmpty();
257 return TRUE;
261 /**************************************************************************
262 * GetClipboardOwner16 (USER.140)
264 HWND16 WINAPI GetClipboardOwner16(void)
266 return hWndClipOwner;
270 /**************************************************************************
271 * GetClipboardOwner32 (USER32.225)
273 HWND WINAPI GetClipboardOwner(void)
275 return hWndClipOwner;
279 /**************************************************************************
280 * SetClipboardData16 (USER.141)
282 HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
284 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
286 TRACE(clipboard, "(%04X, %04x) !\n", wFormat, hData);
288 /* NOTE: If the hData is zero and current owner doesn't match
289 * the window that opened the clipboard then this application
290 * is screwed because WM_RENDERFORMAT will go to the owner
291 * (to become the owner it must call EmptyClipboard() before
292 * adding new data).
295 if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
296 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
298 CLIPBOARD_Driver->pSetData(wFormat);
300 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
302 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
304 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
306 if( wFormat == CF_TEXT
307 && ( ClipFormats[CF_OEMTEXT-1].hData16
308 || ClipFormats[CF_OEMTEXT-1].hData32 )
309 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
310 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
311 if( wFormat == CF_OEMTEXT
312 && ( ClipFormats[CF_OEMTEXT-1].hData16
313 || ClipFormats[CF_OEMTEXT-1].hData32 )
314 && !ClipFormats[CF_TEXT-1].wDataPresent )
315 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
318 bCBHasChanged = TRUE;
319 lpFormat->wDataPresent = 1;
320 lpFormat->hData16 = hData; /* 0 is legal, see WM_RENDERFORMAT */
321 lpFormat->hData32 = 0;
323 return lpFormat->hData16;
327 /**************************************************************************
328 * SetClipboardData (USER32.470)
330 HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData )
332 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
334 TRACE(clipboard, "(%08X, %08x) !\n", wFormat, hData);
336 /* NOTE: If the hData is zero and current owner doesn't match
337 * the window that opened the clipboard then this application
338 * is screwed because WM_RENDERFORMAT will go to the owner
339 * (to become the owner it must call EmptyClipboard() before
340 * adding new data).
343 if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
344 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
346 CLIPBOARD_Driver->pSetData(wFormat);
348 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
350 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
352 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
354 if( wFormat == CF_TEXT
355 && ( ClipFormats[CF_OEMTEXT-1].hData16
356 || ClipFormats[CF_OEMTEXT-1].hData32 )
357 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
358 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
359 if( wFormat == CF_OEMTEXT
360 && ( ClipFormats[CF_OEMTEXT-1].hData16
361 || ClipFormats[CF_OEMTEXT-1].hData32 )
362 && !ClipFormats[CF_TEXT-1].wDataPresent )
363 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
366 bCBHasChanged = TRUE;
367 lpFormat->wDataPresent = 1;
368 lpFormat->hData32 = hData; /* 0 is legal, see WM_RENDERFORMAT */
369 lpFormat->hData16 = 0;
371 return lpFormat->hData32;
375 /**************************************************************************
376 * CLIPBOARD_RenderFormat
378 static BOOL CLIPBOARD_RenderFormat(LPWINE_CLIPFORMAT lpFormat)
380 if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
382 if( IsWindow(hWndClipOwner) )
383 SendMessage16(hWndClipOwner,WM_RENDERFORMAT,
384 (WPARAM16)lpFormat->wFormatID,0L);
385 else
387 WARN(clipboard, "\thWndClipOwner (%04x) is lost!\n",
388 hWndClipOwner);
389 hWndClipOwner = 0; lpFormat->wDataPresent = 0;
390 return FALSE;
393 return (lpFormat->hData16 || lpFormat->hData32) ? TRUE : FALSE;
396 /**************************************************************************
397 * CLIPBOARD_RenderText
399 * Convert text between UNIX and DOS formats.
401 * FIXME: Should be a pair of driver functions that convert between OEM text and Windows.
404 static BOOL CLIPBOARD_RenderText(LPWINE_CLIPFORMAT lpTarget, LPWINE_CLIPFORMAT lpSource)
406 UINT16 size;
407 LPCSTR lpstrS;
408 LPSTR lpstrT;
410 if (lpSource->hData32)
412 size = GlobalSize( lpSource->hData32 );
413 lpstrS = (LPSTR)GlobalLock(lpSource->hData32);
415 else
417 size = GlobalSize16( lpSource->hData16 );
418 lpstrS = (LPSTR)GlobalLock16(lpSource->hData16);
421 if( !lpstrS ) return FALSE;
422 TRACE(clipboard,"\tconverting from '%s' to '%s', %i chars\n",
423 lpSource->Name, lpTarget->Name, size);
425 lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT, size);
426 lpstrT = (LPSTR)GlobalLock(lpTarget->hData32);
428 if( lpstrT )
430 if( lpSource->wFormatID == CF_TEXT )
431 CharToOemBuffA(lpstrS, lpstrT, size);
432 else
433 OemToCharBuffA(lpstrS, lpstrT, size);
434 TRACE(clipboard,"\tgot %s\n", lpstrT);
435 GlobalUnlock(lpTarget->hData32);
436 if (lpSource->hData32)
437 GlobalUnlock(lpSource->hData32);
438 else
439 GlobalUnlock16(lpSource->hData16);
440 return TRUE;
443 lpTarget->hData32 = 0;
444 if (lpSource->hData32)
445 GlobalUnlock(lpSource->hData32);
446 else
447 GlobalUnlock16(lpSource->hData16);
448 return FALSE;
451 /**************************************************************************
452 * GetClipboardData16 (USER.142)
454 HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat )
456 LPWINE_CLIPFORMAT lpRender = ClipFormats;
457 LPWINE_CLIPFORMAT lpUpdate = NULL;
459 if (hqClipLock != GetFastQueue16()) return 0;
461 TRACE(clipboard,"(%04X)\n", wFormat);
463 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
464 && lpRender[CF_OEMTEXT-1].wDataPresent )
466 lpRender = &ClipFormats[CF_OEMTEXT-1];
467 lpUpdate = &ClipFormats[CF_TEXT-1];
469 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
471 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
472 && lpRender[CF_TEXT-1].wDataPresent )
474 lpRender = &ClipFormats[CF_TEXT-1];
475 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
477 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
479 else
481 lpRender = __lookup_format( ClipFormats, wFormat );
482 lpUpdate = lpRender;
485 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
486 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
487 CLIPBOARD_RenderText(lpUpdate, lpRender);
489 if( lpUpdate->hData32 && !lpUpdate->hData16 )
491 int size;
492 if( lpUpdate->wFormatID == CF_METAFILEPICT )
493 size = sizeof( METAFILEPICT16 );
494 else
495 size = GlobalSize(lpUpdate->hData32);
496 lpUpdate->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
497 if( !lpUpdate->hData16 )
498 ERR(clipboard, "(%04X) -- not enough memory in 16b heap\n", wFormat);
499 else
501 if( lpUpdate->wFormatID == CF_METAFILEPICT )
503 FIXME(clipboard,"\timplement function CopyMetaFilePict32to16\n");
504 FIXME(clipboard,"\tin the appropriate file.\n");
505 #ifdef SOMEONE_IMPLEMENTED_ME
506 CopyMetaFilePict32to16( GlobalLock16(lpUpdate->hData16),
507 GlobalLock(lpUpdate->hData32) );
508 #endif
510 else
512 memcpy( GlobalLock16(lpUpdate->hData16),
513 GlobalLock(lpUpdate->hData32),
514 size );
516 GlobalUnlock16(lpUpdate->hData16);
517 GlobalUnlock(lpUpdate->hData32);
521 TRACE(clipboard,"\treturning %04x (type %i)\n",
522 lpUpdate->hData16, lpUpdate->wFormatID);
523 return lpUpdate->hData16;
527 /**************************************************************************
528 * GetClipboardData32 (USER32.222)
530 HANDLE WINAPI GetClipboardData( UINT wFormat )
532 LPWINE_CLIPFORMAT lpRender = ClipFormats;
533 LPWINE_CLIPFORMAT lpUpdate = NULL;
535 if (hqClipLock != GetFastQueue16()) return 0;
537 TRACE(clipboard,"(%08X)\n", wFormat);
539 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
540 && lpRender[CF_OEMTEXT-1].wDataPresent )
542 lpRender = &ClipFormats[CF_OEMTEXT-1];
543 lpUpdate = &ClipFormats[CF_TEXT-1];
545 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
547 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
548 && lpRender[CF_TEXT-1].wDataPresent )
550 lpRender = &ClipFormats[CF_TEXT-1];
551 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
553 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
555 else
557 lpRender = __lookup_format( ClipFormats, wFormat );
558 lpUpdate = lpRender;
561 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
562 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
563 CLIPBOARD_RenderText(lpUpdate, lpRender);
565 if( lpUpdate->hData16 && !lpUpdate->hData32 )
567 int size;
568 if( lpUpdate->wFormatID == CF_METAFILEPICT )
569 size = sizeof( METAFILEPICT );
570 else
571 size = GlobalSize16(lpUpdate->hData16);
572 lpUpdate->hData32 = GlobalAlloc(GMEM_ZEROINIT, size);
573 if( lpUpdate->wFormatID == CF_METAFILEPICT )
575 FIXME(clipboard,"\timplement function CopyMetaFilePict16to32\n");
576 FIXME(clipboard,"\tin the appropriate file.\n");
577 #ifdef SOMEONE_IMPLEMENTED_ME
578 CopyMetaFilePict16to32( GlobalLock16(lpUpdate->hData32),
579 GlobalLock(lpUpdate->hData16) );
580 #endif
582 else
584 memcpy( GlobalLock(lpUpdate->hData32),
585 GlobalLock16(lpUpdate->hData16),
586 size );
588 GlobalUnlock(lpUpdate->hData32);
589 GlobalUnlock16(lpUpdate->hData16);
592 TRACE(clipboard,"\treturning %04x (type %i)\n",
593 lpUpdate->hData32, lpUpdate->wFormatID);
594 return lpUpdate->hData32;
597 /**************************************************************************
598 * CountClipboardFormats16 (USER.143)
600 INT16 WINAPI CountClipboardFormats16(void)
602 return CountClipboardFormats();
606 /**************************************************************************
607 * CountClipboardFormats32 (USER32.63)
609 INT WINAPI CountClipboardFormats(void)
611 INT FormatCount = 0;
612 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
614 TRACE(clipboard,"(void)\n");
616 while(TRUE)
618 if (lpFormat == NULL) break;
620 if( lpFormat->wFormatID != CF_TEXT )
621 CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
623 if (lpFormat->wDataPresent)
625 TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
626 FormatCount++;
628 lpFormat = lpFormat->NextFormat;
631 /* these two are equivalent, adjust the total */
633 FormatCount += abs(ClipFormats[CF_TEXT-1].wDataPresent -
634 ClipFormats[CF_OEMTEXT-1].wDataPresent);
636 TRACE(clipboard,"\ttotal %d\n", FormatCount);
637 return FormatCount;
641 /**************************************************************************
642 * EnumClipboardFormats16 (USER.144)
644 UINT16 WINAPI EnumClipboardFormats16( UINT16 wFormat )
646 return EnumClipboardFormats( wFormat );
650 /**************************************************************************
651 * EnumClipboardFormats32 (USER32.179)
653 UINT WINAPI EnumClipboardFormats( UINT wFormat )
655 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
657 TRACE(clipboard,"(%04X)\n", wFormat);
659 if( hqClipLock != GetFastQueue16() ) return 0;
661 if( wFormat < CF_OEMTEXT )
662 CLIPBOARD_Driver->pGetData( CF_OEMTEXT );
664 if (wFormat == 0) /* start from the beginning */
665 lpFormat = ClipFormats;
666 else
668 /* walk up to the specified format record */
670 if( !(lpFormat = __lookup_format( lpFormat, wFormat )) )
671 return 0;
672 lpFormat = lpFormat->NextFormat; /* right */
675 while(TRUE)
677 if (lpFormat == NULL) return 0;
679 if( lpFormat->wFormatID != CF_OEMTEXT && lpFormat->wFormatID != CF_TEXT )
680 CLIPBOARD_Driver->pGetData( lpFormat->wFormatID );
682 if (lpFormat->wDataPresent ||
683 (lpFormat->wFormatID == CF_OEMTEXT && ClipFormats[CF_TEXT-1].wDataPresent) ||
684 (lpFormat->wFormatID == CF_TEXT && ClipFormats[CF_OEMTEXT-1].wDataPresent) )
685 break;
686 lpFormat = lpFormat->NextFormat;
689 return lpFormat->wFormatID;
693 /**************************************************************************
694 * RegisterClipboardFormat16 (USER.145)
696 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR FormatName )
698 LPWINE_CLIPFORMAT lpNewFormat;
699 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
701 if (FormatName == NULL) return 0;
703 TRACE(clipboard,"('%s') !\n", FormatName);
705 /* walk format chain to see if it's already registered */
707 while(TRUE)
709 if ( !strcmp(lpFormat->Name,FormatName) )
711 lpFormat->wRefCount++;
712 return lpFormat->wFormatID;
715 if ( lpFormat->NextFormat == NULL ) break;
717 lpFormat = lpFormat->NextFormat;
720 /* allocate storage for new format entry */
722 lpNewFormat = (LPWINE_CLIPFORMAT)xmalloc(sizeof(WINE_CLIPFORMAT));
723 lpFormat->NextFormat = lpNewFormat;
724 lpNewFormat->wFormatID = LastRegFormat;
725 lpNewFormat->wRefCount = 1;
727 lpNewFormat->Name = (LPSTR)xmalloc(strlen(FormatName) + 1);
728 strcpy(lpNewFormat->Name, FormatName);
730 lpNewFormat->wDataPresent = 0;
731 lpNewFormat->hData16 = 0;
732 lpNewFormat->hData32 = 0;
733 lpNewFormat->BufSize = 0;
734 lpNewFormat->PrevFormat = lpFormat;
735 lpNewFormat->NextFormat = NULL;
737 return LastRegFormat++;
741 /**************************************************************************
742 * RegisterClipboardFormat32A (USER32.431)
744 UINT WINAPI RegisterClipboardFormatA( LPCSTR formatName )
746 return RegisterClipboardFormat16( formatName );
750 /**************************************************************************
751 * RegisterClipboardFormat32W (USER32.432)
753 UINT WINAPI RegisterClipboardFormatW( LPCWSTR formatName )
755 LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
756 UINT ret = RegisterClipboardFormatA( aFormat );
757 HeapFree( GetProcessHeap(), 0, aFormat );
758 return ret;
761 /**************************************************************************
762 * GetClipboardFormatName16 (USER.146)
764 INT16 WINAPI GetClipboardFormatName16( UINT16 wFormat, LPSTR retStr, INT16 maxlen )
766 return GetClipboardFormatNameA( wFormat, retStr, maxlen );
770 /**************************************************************************
771 * GetClipboardFormatName32A (USER32.223)
773 INT WINAPI GetClipboardFormatNameA( UINT wFormat, LPSTR retStr, INT maxlen )
775 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
777 TRACE(clipboard, "(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
779 if (lpFormat == NULL || lpFormat->Name == NULL ||
780 lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
782 TRACE(clipboard, "Name='%s' !\n", lpFormat->Name);
784 lstrcpynA( retStr, lpFormat->Name, maxlen );
785 return strlen(retStr);
789 /**************************************************************************
790 * GetClipboardFormatName32W (USER32.224)
792 INT WINAPI GetClipboardFormatNameW( UINT wFormat, LPWSTR retStr, INT maxlen )
794 LPSTR p = HEAP_xalloc( GetProcessHeap(), 0, maxlen );
795 INT ret = GetClipboardFormatNameA( wFormat, p, maxlen );
796 lstrcpynAtoW( retStr, p, maxlen );
797 HeapFree( GetProcessHeap(), 0, p );
798 return ret;
802 /**************************************************************************
803 * SetClipboardViewer16 (USER.147)
805 HWND16 WINAPI SetClipboardViewer16( HWND16 hWnd )
807 return SetClipboardViewer( hWnd );
811 /**************************************************************************
812 * SetClipboardViewer32 (USER32.471)
814 HWND WINAPI SetClipboardViewer( HWND hWnd )
816 HWND hwndPrev = hWndViewer;
818 TRACE(clipboard,"(%04x): returning %04x\n", hWnd, hwndPrev);
820 hWndViewer = hWnd;
821 return hwndPrev;
825 /**************************************************************************
826 * GetClipboardViewer16 (USER.148)
828 HWND16 WINAPI GetClipboardViewer16(void)
830 return hWndViewer;
834 /**************************************************************************
835 * GetClipboardViewer32 (USER32.226)
837 HWND WINAPI GetClipboardViewer(void)
839 return hWndViewer;
843 /**************************************************************************
844 * ChangeClipboardChain16 (USER.149)
846 BOOL16 WINAPI ChangeClipboardChain16(HWND16 hWnd, HWND16 hWndNext)
848 return ChangeClipboardChain(hWnd, hWndNext);
851 /**************************************************************************
852 * ChangeClipboardChain32 (USER32.22)
854 BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext)
856 BOOL bRet = 0;
858 FIXME(clipboard, "(0x%04x, 0x%04x): stub?\n", hWnd, hWndNext);
860 if( hWndViewer )
861 bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
862 (WPARAM16)hWnd, (LPARAM)hWndNext);
863 else
864 WARN(clipboard, "hWndViewer is lost\n");
866 if( hWnd == hWndViewer ) hWndViewer = hWndNext;
868 return bRet;
873 /**************************************************************************
874 * IsClipboardFormatAvailable16 (USER.193)
876 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
878 return IsClipboardFormatAvailable( wFormat );
882 /**************************************************************************
883 * IsClipboardFormatAvailable32 (USER32.340)
885 BOOL WINAPI IsClipboardFormatAvailable( UINT wFormat )
887 TRACE(clipboard,"(%04X) !\n", wFormat);
889 CLIPBOARD_Driver->pGetData( (wFormat == CF_TEXT) ? CF_OEMTEXT : wFormat );
891 return CLIPBOARD_IsPresent(wFormat);
895 /**************************************************************************
896 * GetOpenClipboardWindow16 (USER.248)
898 HWND16 WINAPI GetOpenClipboardWindow16(void)
900 return hWndClipWindow;
904 /**************************************************************************
905 * GetOpenClipboardWindow32 (USER32.277)
907 HWND WINAPI GetOpenClipboardWindow(void)
909 return hWndClipWindow;
913 /**************************************************************************
914 * GetPriorityClipboardFormat16 (USER.402)
916 INT16 WINAPI GetPriorityClipboardFormat16( UINT16 *lpPriorityList, INT16 nCount)
918 FIXME(clipboard, "(%p,%d): stub\n", lpPriorityList, nCount );
919 return 0;
923 /**************************************************************************
924 * GetPriorityClipboardFormat32 (USER32.279)
926 INT WINAPI GetPriorityClipboardFormat( UINT *lpPriorityList, INT nCount )
928 int Counter;
930 if(CountClipboardFormats() == 0)
932 return 0;
935 for(Counter = 0; Counter <= nCount; Counter++)
937 if(IsClipboardFormatAvailable(*(lpPriorityList+sizeof(INT)*Counter)))
938 return *(lpPriorityList+sizeof(INT)*Counter);
941 return -1;