Fixed a simple bug in the implementation of the ShellView objects.
[wine/dcerpc.git] / windows / clipboard.c
blobc7af89c26a97f9b784626e28bbccf1611d822071
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 #ifndef X_DISPLAY_MISSING
25 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver;
26 #else /* X_DISPLAY_MISSING */
27 extern CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver;
28 #endif /* X_DISPLAY_MISSING */
30 #define CF_REGFORMATBASE 0xC000
32 /**************************************************************************
33 * internal variables
36 static HQUEUE16 hqClipLock = 0;
37 static BOOL bCBHasChanged = FALSE;
39 HWND hWndClipOwner = 0; /* current clipboard owner */
40 HWND hWndClipWindow = 0; /* window that opened clipboard */
41 static HWND hWndViewer = 0; /* start of viewers chain */
43 static WORD LastRegFormat = CF_REGFORMATBASE;
45 WINE_CLIPFORMAT ClipFormats[16] = {
46 { CF_TEXT, 1, 0, "Text", (HANDLE)NULL, 0, NULL, &ClipFormats[1] , (HANDLE16)NULL},
47 { CF_BITMAP, 1, 0, "Bitmap", (HANDLE)NULL, 0, &ClipFormats[0], &ClipFormats[2] , (HANDLE16)NULL},
48 { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[1], &ClipFormats[3] , (HANDLE16)NULL},
49 { CF_SYLK, 1, 0, "Sylk", (HANDLE)NULL, 0, &ClipFormats[2], &ClipFormats[4] , (HANDLE16)NULL},
50 { CF_DIF, 1, 0, "DIF", (HANDLE)NULL, 0, &ClipFormats[3], &ClipFormats[5] , (HANDLE16)NULL},
51 { CF_TIFF, 1, 0, "TIFF", (HANDLE)NULL, 0, &ClipFormats[4], &ClipFormats[6] , (HANDLE16)NULL},
52 { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE)NULL, 0, &ClipFormats[5], &ClipFormats[7] , (HANDLE16)NULL},
53 { CF_DIB, 1, 0, "DIB", (HANDLE)NULL, 0, &ClipFormats[6], &ClipFormats[8] , (HANDLE16)NULL},
54 { CF_PALETTE, 1, 0, "Palette", (HANDLE)NULL, 0, &ClipFormats[7], &ClipFormats[9] , (HANDLE16)NULL},
55 { CF_PENDATA, 1, 0, "PenData", (HANDLE)NULL, 0, &ClipFormats[8], &ClipFormats[10] , (HANDLE16)NULL},
56 { CF_RIFF, 1, 0, "RIFF", (HANDLE)NULL, 0, &ClipFormats[9], &ClipFormats[11] , (HANDLE16)NULL},
57 { CF_WAVE, 1, 0, "Wave", (HANDLE)NULL, 0, &ClipFormats[10], &ClipFormats[12] , (HANDLE16)NULL},
58 { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE)NULL, 0, &ClipFormats[11], &ClipFormats[13] , (HANDLE16)NULL},
59 { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE)NULL, 0, &ClipFormats[12], &ClipFormats[14] , (HANDLE16)NULL},
60 { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE)NULL, 0, &ClipFormats[13], &ClipFormats[15] , (HANDLE16)NULL},
61 { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE)NULL, 0, &ClipFormats[14], NULL , (HANDLE16)NULL}
64 static LPWINE_CLIPFORMAT __lookup_format( LPWINE_CLIPFORMAT lpFormat, WORD wID )
66 while(TRUE)
68 if (lpFormat == NULL ||
69 lpFormat->wFormatID == wID) break;
70 lpFormat = lpFormat->NextFormat;
72 return lpFormat;
76 /**************************************************************************
77 * CLIPBOARD_GetDriver
79 CLIPBOARD_DRIVER *CLIPBOARD_GetDriver()
81 #ifndef X_DISPLAY_MISSING
82 return &X11DRV_CLIPBOARD_Driver;
83 #else /* X_DISPLAY_MISSING */
84 return &TTYDRV_CLIPBOARD_Driver;
85 #endif /* X_DISPLAY_MISSING */
88 /**************************************************************************
89 * CLIPBOARD_ResetLock
91 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent, HQUEUE16 hqNew )
93 if( hqClipLock == hqCurrent )
95 if( hqNew )
96 hqClipLock = hqNew;
97 else
99 hWndClipOwner = 0;
100 hWndClipWindow = 0;
101 EmptyClipboard();
102 hqClipLock = 0;
108 /**************************************************************************
109 * CLIPBOARD_DeleteRecord
111 void CLIPBOARD_DeleteRecord(LPWINE_CLIPFORMAT lpFormat, BOOL bChange)
113 if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
114 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP )
116 if (lpFormat->hData32)
117 DeleteObject(lpFormat->hData32);
118 if (lpFormat->hData16)
119 DeleteObject16(lpFormat->hData16);
121 else if( lpFormat->wFormatID == CF_METAFILEPICT )
123 if (lpFormat->hData32)
125 DeleteMetaFile( ((METAFILEPICT *)GlobalLock( lpFormat->hData32 ))->hMF );
126 GlobalFree(lpFormat->hData32);
127 if (lpFormat->hData16)
128 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
129 and a shallow copy is enough to share a METAFILEPICT
130 structure between 16bit and 32bit clipboards. The MetaFile
131 should of course only be deleted once. */
132 GlobalFree16(lpFormat->hData16);
134 else if (lpFormat->hData16)
136 DeleteMetaFile16( ((METAFILEPICT16 *)GlobalLock16( lpFormat->hData16 ))->hMF );
137 GlobalFree16(lpFormat->hData16);
140 else
142 if (lpFormat->hData32)
143 GlobalFree(lpFormat->hData32);
144 if (lpFormat->hData16)
145 GlobalFree16(lpFormat->hData16);
148 lpFormat->wDataPresent = 0;
149 lpFormat->hData16 = 0;
150 lpFormat->hData32 = 0;
152 if( bChange ) bCBHasChanged = TRUE;
155 /**************************************************************************
156 * CLIPBOARD_IsPresent
158 BOOL CLIPBOARD_IsPresent(WORD wFormat)
160 /* special case */
162 if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
163 return ClipFormats[CF_TEXT-1].wDataPresent ||
164 ClipFormats[CF_OEMTEXT-1].wDataPresent;
165 else
167 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
168 if( lpFormat ) return (lpFormat->wDataPresent);
170 return FALSE;
173 /**************************************************************************
174 * OpenClipboard16 (USER.137)
176 BOOL16 WINAPI OpenClipboard16( HWND16 hWnd )
178 return OpenClipboard( hWnd );
182 /**************************************************************************
183 * OpenClipboard32 (USER32.407)
185 * Note: Netscape uses NULL hWnd to open the clipboard.
187 BOOL WINAPI OpenClipboard( HWND hWnd )
189 BOOL bRet;
191 TRACE(clipboard,"(%04x)...\n", hWnd);
193 if (!hqClipLock)
195 hqClipLock = GetFastQueue16();
196 hWndClipWindow = hWnd;
197 bCBHasChanged = FALSE;
198 bRet = TRUE;
200 else bRet = FALSE;
202 TRACE(clipboard," returning %i\n", bRet);
203 return bRet;
207 /**************************************************************************
208 * CloseClipboard16 (USER.138)
210 BOOL16 WINAPI CloseClipboard16(void)
212 return CloseClipboard();
216 /**************************************************************************
217 * CloseClipboard32 (USER32.54)
219 BOOL WINAPI CloseClipboard(void)
221 TRACE(clipboard,"!\n");
223 if (hqClipLock == GetFastQueue16())
225 hWndClipWindow = 0;
227 if (bCBHasChanged && hWndViewer)
228 SendMessage16(hWndViewer, WM_DRAWCLIPBOARD, 0, 0L);
229 hqClipLock = 0;
231 return TRUE;
235 /**************************************************************************
236 * EmptyClipboard16 (USER.139)
238 BOOL16 WINAPI EmptyClipboard16(void)
240 return EmptyClipboard();
244 /**************************************************************************
245 * EmptyClipboard32 (USER32.169)
247 BOOL WINAPI EmptyClipboard(void)
249 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
251 TRACE(clipboard,"(void)\n");
253 if (hqClipLock != GetFastQueue16()) return FALSE;
255 /* destroy private objects */
257 if (hWndClipOwner)
258 SendMessage16(hWndClipOwner, WM_DESTROYCLIPBOARD, 0, 0L);
260 while(lpFormat)
262 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
263 CLIPBOARD_DeleteRecord( lpFormat, TRUE );
265 lpFormat = lpFormat->NextFormat;
268 hWndClipOwner = hWndClipWindow;
270 CLIPBOARD_GetDriver()->pEmptyClipboard();
272 return TRUE;
276 /**************************************************************************
277 * GetClipboardOwner16 (USER.140)
279 HWND16 WINAPI GetClipboardOwner16(void)
281 return hWndClipOwner;
285 /**************************************************************************
286 * GetClipboardOwner32 (USER32.225)
288 HWND WINAPI GetClipboardOwner(void)
290 return hWndClipOwner;
294 /**************************************************************************
295 * SetClipboardData16 (USER.141)
297 HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
299 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
301 TRACE(clipboard, "(%04X, %04x) !\n", wFormat, hData);
303 /* NOTE: If the hData is zero and current owner doesn't match
304 * the window that opened the clipboard then this application
305 * is screwed because WM_RENDERFORMAT will go to the owner
306 * (to become the owner it must call EmptyClipboard() before
307 * adding new data).
310 if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
311 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
313 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
315 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
317 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
319 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
321 if( wFormat == CF_TEXT
322 && ( ClipFormats[CF_OEMTEXT-1].hData16
323 || ClipFormats[CF_OEMTEXT-1].hData32 )
324 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
325 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
326 if( wFormat == CF_OEMTEXT
327 && ( ClipFormats[CF_OEMTEXT-1].hData16
328 || ClipFormats[CF_OEMTEXT-1].hData32 )
329 && !ClipFormats[CF_TEXT-1].wDataPresent )
330 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
333 bCBHasChanged = TRUE;
334 lpFormat->wDataPresent = 1;
335 lpFormat->hData16 = hData; /* 0 is legal, see WM_RENDERFORMAT */
336 lpFormat->hData32 = 0;
338 return lpFormat->hData16;
342 /**************************************************************************
343 * SetClipboardData32 (USER32.470)
345 HANDLE WINAPI SetClipboardData( UINT wFormat, HANDLE hData )
347 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
349 TRACE(clipboard, "(%08X, %08x) !\n", wFormat, hData);
351 /* NOTE: If the hData is zero and current owner doesn't match
352 * the window that opened the clipboard then this application
353 * is screwed because WM_RENDERFORMAT will go to the owner
354 * (to become the owner it must call EmptyClipboard() before
355 * adding new data).
358 if( (hqClipLock != GetFastQueue16()) || !lpFormat ||
359 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
361 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
363 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
365 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
367 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
369 if( wFormat == CF_TEXT
370 && ( ClipFormats[CF_OEMTEXT-1].hData16
371 || ClipFormats[CF_OEMTEXT-1].hData32 )
372 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
373 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
374 if( wFormat == CF_OEMTEXT
375 && ( ClipFormats[CF_OEMTEXT-1].hData16
376 || ClipFormats[CF_OEMTEXT-1].hData32 )
377 && !ClipFormats[CF_TEXT-1].wDataPresent )
378 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
381 bCBHasChanged = TRUE;
382 lpFormat->wDataPresent = 1;
383 lpFormat->hData32 = hData; /* 0 is legal, see WM_RENDERFORMAT */
384 lpFormat->hData16 = 0;
386 return lpFormat->hData32;
390 /**************************************************************************
391 * CLIPBOARD_RenderFormat
393 static BOOL CLIPBOARD_RenderFormat(LPWINE_CLIPFORMAT lpFormat)
395 if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
397 if( IsWindow(hWndClipOwner) )
398 SendMessage16(hWndClipOwner,WM_RENDERFORMAT,
399 (WPARAM16)lpFormat->wFormatID,0L);
400 else
402 WARN(clipboard, "\thWndClipOwner (%04x) is lost!\n",
403 hWndClipOwner);
404 hWndClipOwner = 0; lpFormat->wDataPresent = 0;
405 return FALSE;
408 return (lpFormat->hData16 || lpFormat->hData32) ? TRUE : FALSE;
411 /**************************************************************************
412 * CLIPBOARD_RenderText
414 * Convert text between UNIX and DOS formats.
416 static BOOL CLIPBOARD_RenderText(LPWINE_CLIPFORMAT lpTarget, LPWINE_CLIPFORMAT lpSource)
418 UINT16 size;
419 LPCSTR lpstrS;
420 LPSTR lpstrT;
422 if (lpSource->hData32)
424 size = GlobalSize( lpSource->hData32 );
425 lpstrS = (LPSTR)GlobalLock(lpSource->hData32);
427 else
429 size = GlobalSize16( lpSource->hData16 );
430 lpstrS = (LPSTR)GlobalLock16(lpSource->hData16);
433 if( !lpstrS ) return FALSE;
434 TRACE(clipboard,"\tconverting from '%s' to '%s', %i chars\n",
435 lpSource->Name, lpTarget->Name, size);
437 lpTarget->hData32 = GlobalAlloc(GMEM_ZEROINIT, size);
438 lpstrT = (LPSTR)GlobalLock(lpTarget->hData32);
440 if( lpstrT )
442 if( lpSource->wFormatID == CF_TEXT )
443 CharToOemBuffA(lpstrS, lpstrT, size);
444 else
445 OemToCharBuffA(lpstrS, lpstrT, size);
446 TRACE(clipboard,"\tgot %s\n", lpstrT);
447 GlobalUnlock(lpTarget->hData32);
448 if (lpSource->hData32)
449 GlobalUnlock(lpSource->hData32);
450 else
451 GlobalUnlock16(lpSource->hData16);
452 return TRUE;
455 lpTarget->hData32 = 0;
456 if (lpSource->hData32)
457 GlobalUnlock(lpSource->hData32);
458 else
459 GlobalUnlock16(lpSource->hData16);
460 return FALSE;
463 /**************************************************************************
464 * GetClipboardData16 (USER.142)
466 HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat )
468 LPWINE_CLIPFORMAT lpRender = ClipFormats;
469 LPWINE_CLIPFORMAT lpUpdate = NULL;
471 if (hqClipLock != GetFastQueue16()) return 0;
473 TRACE(clipboard,"(%04X)\n", wFormat);
475 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
476 && lpRender[CF_OEMTEXT-1].wDataPresent )
478 lpRender = &ClipFormats[CF_OEMTEXT-1];
479 lpUpdate = &ClipFormats[CF_TEXT-1];
481 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
483 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
484 && lpRender[CF_TEXT-1].wDataPresent )
486 lpRender = &ClipFormats[CF_TEXT-1];
487 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
489 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
491 else
493 lpRender = __lookup_format( ClipFormats, wFormat );
494 lpUpdate = lpRender;
497 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
498 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
499 CLIPBOARD_RenderText(lpUpdate, lpRender);
501 if( lpUpdate->hData32 && !lpUpdate->hData16 )
503 int size;
504 if( lpUpdate->wFormatID == CF_METAFILEPICT )
505 size = sizeof( METAFILEPICT16 );
506 else
507 size = GlobalSize(lpUpdate->hData32);
508 lpUpdate->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
509 if( !lpUpdate->hData16 )
510 ERR(clipboard, "(%04X) -- not enough memory in 16b heap\n", wFormat);
511 else
513 if( lpUpdate->wFormatID == CF_METAFILEPICT )
515 FIXME(clipboard,"\timplement function CopyMetaFilePict32to16\n");
516 FIXME(clipboard,"\tin the appropriate file.\n");
517 #ifdef SOMEONE_IMPLEMENTED_ME
518 CopyMetaFilePict32to16( GlobalLock16(lpUpdate->hData16),
519 GlobalLock(lpUpdate->hData32) );
520 #endif
522 else
524 memcpy( GlobalLock16(lpUpdate->hData16),
525 GlobalLock(lpUpdate->hData32),
526 size );
528 GlobalUnlock16(lpUpdate->hData16);
529 GlobalUnlock(lpUpdate->hData32);
533 TRACE(clipboard,"\treturning %04x (type %i)\n",
534 lpUpdate->hData16, lpUpdate->wFormatID);
535 return lpUpdate->hData16;
539 /**************************************************************************
540 * GetClipboardData32 (USER32.222)
542 HANDLE WINAPI GetClipboardData( UINT wFormat )
544 LPWINE_CLIPFORMAT lpRender = ClipFormats;
545 LPWINE_CLIPFORMAT lpUpdate = NULL;
547 if (hqClipLock != GetFastQueue16()) return 0;
549 TRACE(clipboard,"(%08X)\n", wFormat);
551 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
552 && lpRender[CF_OEMTEXT-1].wDataPresent )
554 lpRender = &ClipFormats[CF_OEMTEXT-1];
555 lpUpdate = &ClipFormats[CF_TEXT-1];
557 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
559 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
560 && lpRender[CF_TEXT-1].wDataPresent )
562 lpRender = &ClipFormats[CF_TEXT-1];
563 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
565 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
567 else
569 lpRender = __lookup_format( ClipFormats, wFormat );
570 lpUpdate = lpRender;
573 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
574 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
575 CLIPBOARD_RenderText(lpUpdate, lpRender);
577 if( lpUpdate->hData16 && !lpUpdate->hData32 )
579 int size;
580 if( lpUpdate->wFormatID == CF_METAFILEPICT )
581 size = sizeof( METAFILEPICT );
582 else
583 size = GlobalSize16(lpUpdate->hData16);
584 lpUpdate->hData32 = GlobalAlloc(GMEM_ZEROINIT, size);
585 if( lpUpdate->wFormatID == CF_METAFILEPICT )
587 FIXME(clipboard,"\timplement function CopyMetaFilePict16to32\n");
588 FIXME(clipboard,"\tin the appropriate file.\n");
589 #ifdef SOMEONE_IMPLEMENTED_ME
590 CopyMetaFilePict16to32( GlobalLock16(lpUpdate->hData32),
591 GlobalLock(lpUpdate->hData16) );
592 #endif
594 else
596 memcpy( GlobalLock(lpUpdate->hData32),
597 GlobalLock16(lpUpdate->hData16),
598 size );
600 GlobalUnlock(lpUpdate->hData32);
601 GlobalUnlock16(lpUpdate->hData16);
604 TRACE(clipboard,"\treturning %04x (type %i)\n",
605 lpUpdate->hData32, lpUpdate->wFormatID);
606 return lpUpdate->hData32;
609 /**************************************************************************
610 * CountClipboardFormats16 (USER.143)
612 INT16 WINAPI CountClipboardFormats16(void)
614 return CountClipboardFormats();
618 /**************************************************************************
619 * CountClipboardFormats32 (USER32.63)
621 INT WINAPI CountClipboardFormats(void)
623 INT FormatCount = 0;
624 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
626 TRACE(clipboard,"(void)\n");
628 /* FIXME: Returns BOOL32 */
629 CLIPBOARD_GetDriver()->pRequestSelection();
631 FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
632 lpFormat[CF_OEMTEXT-1].wDataPresent);
634 while(TRUE)
636 if (lpFormat == NULL) break;
637 if (lpFormat->wDataPresent)
639 TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
640 FormatCount++;
642 lpFormat = lpFormat->NextFormat;
645 TRACE(clipboard,"\ttotal %d\n", FormatCount);
646 return FormatCount;
650 /**************************************************************************
651 * EnumClipboardFormats16 (USER.144)
653 UINT16 WINAPI EnumClipboardFormats16( UINT16 wFormat )
655 return EnumClipboardFormats( wFormat );
659 /**************************************************************************
660 * EnumClipboardFormats32 (USER32.179)
662 UINT WINAPI EnumClipboardFormats( UINT wFormat )
664 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
666 TRACE(clipboard,"(%04X)\n", wFormat);
668 if( hqClipLock != GetFastQueue16() ) return 0;
670 if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
671 CLIPBOARD_GetDriver()->pRequestSelection();
673 if (wFormat == 0)
675 if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent)
676 return lpFormat->wFormatID;
677 else
678 wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
681 /* walk up to the specified format record */
683 if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) return 0;
685 /* find next format with available data */
687 lpFormat = lpFormat->NextFormat;
688 while(TRUE)
690 if (lpFormat == NULL) return 0;
691 if (lpFormat->wDataPresent || (lpFormat->wFormatID == CF_OEMTEXT &&
692 ClipFormats[CF_TEXT-1].wDataPresent))
693 break;
694 lpFormat = lpFormat->NextFormat;
697 return lpFormat->wFormatID;
701 /**************************************************************************
702 * RegisterClipboardFormat16 (USER.145)
704 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR FormatName )
706 LPWINE_CLIPFORMAT lpNewFormat;
707 LPWINE_CLIPFORMAT lpFormat = ClipFormats;
709 if (FormatName == NULL) return 0;
711 TRACE(clipboard,"('%s') !\n", FormatName);
713 /* walk format chain to see if it's already registered */
715 while(TRUE)
717 if ( !strcmp(lpFormat->Name,FormatName) )
719 lpFormat->wRefCount++;
720 return lpFormat->wFormatID;
723 if ( lpFormat->NextFormat == NULL ) break;
725 lpFormat = lpFormat->NextFormat;
728 /* allocate storage for new format entry */
730 lpNewFormat = (LPWINE_CLIPFORMAT)xmalloc(sizeof(WINE_CLIPFORMAT));
731 lpFormat->NextFormat = lpNewFormat;
732 lpNewFormat->wFormatID = LastRegFormat;
733 lpNewFormat->wRefCount = 1;
735 lpNewFormat->Name = (LPSTR)xmalloc(strlen(FormatName) + 1);
736 strcpy(lpNewFormat->Name, FormatName);
738 lpNewFormat->wDataPresent = 0;
739 lpNewFormat->hData16 = 0;
740 lpNewFormat->hData32 = 0;
741 lpNewFormat->BufSize = 0;
742 lpNewFormat->PrevFormat = lpFormat;
743 lpNewFormat->NextFormat = NULL;
745 return LastRegFormat++;
749 /**************************************************************************
750 * RegisterClipboardFormat32A (USER32.431)
752 UINT WINAPI RegisterClipboardFormatA( LPCSTR formatName )
754 return RegisterClipboardFormat16( formatName );
758 /**************************************************************************
759 * RegisterClipboardFormat32W (USER32.432)
761 UINT WINAPI RegisterClipboardFormatW( LPCWSTR formatName )
763 LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
764 UINT ret = RegisterClipboardFormatA( aFormat );
765 HeapFree( GetProcessHeap(), 0, aFormat );
766 return ret;
769 /**************************************************************************
770 * GetClipboardFormatName16 (USER.146)
772 INT16 WINAPI GetClipboardFormatName16( UINT16 wFormat, LPSTR retStr, INT16 maxlen )
774 return GetClipboardFormatNameA( wFormat, retStr, maxlen );
778 /**************************************************************************
779 * GetClipboardFormatName32A (USER32.223)
781 INT WINAPI GetClipboardFormatNameA( UINT wFormat, LPSTR retStr, INT maxlen )
783 LPWINE_CLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
785 TRACE(clipboard, "(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
787 if (lpFormat == NULL || lpFormat->Name == NULL ||
788 lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
790 TRACE(clipboard, "Name='%s' !\n", lpFormat->Name);
792 lstrcpynA( retStr, lpFormat->Name, maxlen );
793 return strlen(retStr);
797 /**************************************************************************
798 * GetClipboardFormatName32W (USER32.224)
800 INT WINAPI GetClipboardFormatNameW( UINT wFormat, LPWSTR retStr, INT maxlen )
802 LPSTR p = HEAP_xalloc( GetProcessHeap(), 0, maxlen );
803 INT ret = GetClipboardFormatNameA( wFormat, p, maxlen );
804 lstrcpynAtoW( retStr, p, maxlen );
805 HeapFree( GetProcessHeap(), 0, p );
806 return ret;
810 /**************************************************************************
811 * SetClipboardViewer16 (USER.147)
813 HWND16 WINAPI SetClipboardViewer16( HWND16 hWnd )
815 return SetClipboardViewer( hWnd );
819 /**************************************************************************
820 * SetClipboardViewer32 (USER32.471)
822 HWND WINAPI SetClipboardViewer( HWND hWnd )
824 HWND hwndPrev = hWndViewer;
826 TRACE(clipboard,"(%04x): returning %04x\n", hWnd, hwndPrev);
828 hWndViewer = hWnd;
829 return hwndPrev;
833 /**************************************************************************
834 * GetClipboardViewer16 (USER.148)
836 HWND16 WINAPI GetClipboardViewer16(void)
838 return hWndViewer;
842 /**************************************************************************
843 * GetClipboardViewer32 (USER32.226)
845 HWND WINAPI GetClipboardViewer(void)
847 return hWndViewer;
851 /**************************************************************************
852 * ChangeClipboardChain16 (USER.149)
854 BOOL16 WINAPI ChangeClipboardChain16(HWND16 hWnd, HWND16 hWndNext)
856 return ChangeClipboardChain(hWnd, hWndNext);
859 /**************************************************************************
860 * ChangeClipboardChain32 (USER32.22)
862 BOOL WINAPI ChangeClipboardChain(HWND hWnd, HWND hWndNext)
864 BOOL bRet = 0;
866 FIXME(clipboard, "(0x%04x, 0x%04x): stub?\n", hWnd, hWndNext);
868 if( hWndViewer )
869 bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
870 (WPARAM16)hWnd, (LPARAM)hWndNext);
871 else
872 WARN(clipboard, "hWndViewer is lost\n");
874 if( hWnd == hWndViewer ) hWndViewer = hWndNext;
876 return bRet;
881 /**************************************************************************
882 * IsClipboardFormatAvailable16 (USER.193)
884 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
886 return IsClipboardFormatAvailable( wFormat );
890 /**************************************************************************
891 * IsClipboardFormatAvailable32 (USER32.340)
893 BOOL WINAPI IsClipboardFormatAvailable( UINT wFormat )
895 TRACE(clipboard,"(%04X) !\n", wFormat);
897 if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
898 CLIPBOARD_GetDriver()->pRequestSelection();
900 return CLIPBOARD_IsPresent(wFormat);
904 /**************************************************************************
905 * GetOpenClipboardWindow16 (USER.248)
907 HWND16 WINAPI GetOpenClipboardWindow16(void)
909 return hWndClipWindow;
913 /**************************************************************************
914 * GetOpenClipboardWindow32 (USER32.277)
916 HWND WINAPI GetOpenClipboardWindow(void)
918 return hWndClipWindow;
922 /**************************************************************************
923 * GetPriorityClipboardFormat16 (USER.402)
925 INT16 WINAPI GetPriorityClipboardFormat16( UINT16 *lpPriorityList, INT16 nCount)
927 FIXME(clipboard, "(%p,%d): stub\n", lpPriorityList, nCount );
928 return 0;
932 /**************************************************************************
933 * GetPriorityClipboardFormat32 (USER32.279)
935 INT WINAPI GetPriorityClipboardFormat( UINT *lpPriorityList, INT nCount )
937 int Counter;
939 if(CountClipboardFormats() == 0)
941 return 0;
944 for(Counter = 0; Counter <= nCount; Counter++)
946 if(IsClipboardFormatAvailable(*(lpPriorityList+sizeof(INT)*Counter)))
947 return *(lpPriorityList+sizeof(INT)*Counter);
950 return -1;