Some more recursive include fixes/optimizations.
[wine.git] / windows / clipboard.c
blobbcc4f154e69ac6161199ce151f86c864fb0bf53c
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 "heap.h"
17 #include "task.h"
18 #include "message.h"
19 #include "clipboard.h"
20 #include "xmalloc.h"
21 #include "debug.h"
23 #ifndef X_DISPLAY_MISSING
24 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver;
25 #else /* X_DISPLAY_MISSING */
26 extern CLIPBOARD_DRIVER TTYDRV_CLIPBOARD_Driver;
27 #endif /* X_DISPLAY_MISSING */
29 #define CF_REGFORMATBASE 0xC000
31 /**************************************************************************
32 * internal variables
35 static HQUEUE16 hqClipLock = 0;
36 static BOOL32 bCBHasChanged = FALSE;
38 HWND32 hWndClipOwner = 0; /* current clipboard owner */
39 HWND32 hWndClipWindow = 0; /* window that opened clipboard */
40 static HWND32 hWndViewer = 0; /* start of viewers chain */
42 static WORD LastRegFormat = CF_REGFORMATBASE;
44 CLIPFORMAT ClipFormats[16] = {
45 { CF_TEXT, 1, 0, "Text", (HANDLE32)NULL, 0, NULL, &ClipFormats[1] , (HANDLE16)NULL},
46 { CF_BITMAP, 1, 0, "Bitmap", (HANDLE32)NULL, 0, &ClipFormats[0], &ClipFormats[2] , (HANDLE16)NULL},
47 { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE32)NULL, 0, &ClipFormats[1], &ClipFormats[3] , (HANDLE16)NULL},
48 { CF_SYLK, 1, 0, "Sylk", (HANDLE32)NULL, 0, &ClipFormats[2], &ClipFormats[4] , (HANDLE16)NULL},
49 { CF_DIF, 1, 0, "DIF", (HANDLE32)NULL, 0, &ClipFormats[3], &ClipFormats[5] , (HANDLE16)NULL},
50 { CF_TIFF, 1, 0, "TIFF", (HANDLE32)NULL, 0, &ClipFormats[4], &ClipFormats[6] , (HANDLE16)NULL},
51 { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE32)NULL, 0, &ClipFormats[5], &ClipFormats[7] , (HANDLE16)NULL},
52 { CF_DIB, 1, 0, "DIB", (HANDLE32)NULL, 0, &ClipFormats[6], &ClipFormats[8] , (HANDLE16)NULL},
53 { CF_PALETTE, 1, 0, "Palette", (HANDLE32)NULL, 0, &ClipFormats[7], &ClipFormats[9] , (HANDLE16)NULL},
54 { CF_PENDATA, 1, 0, "PenData", (HANDLE32)NULL, 0, &ClipFormats[8], &ClipFormats[10] , (HANDLE16)NULL},
55 { CF_RIFF, 1, 0, "RIFF", (HANDLE32)NULL, 0, &ClipFormats[9], &ClipFormats[11] , (HANDLE16)NULL},
56 { CF_WAVE, 1, 0, "Wave", (HANDLE32)NULL, 0, &ClipFormats[10], &ClipFormats[12] , (HANDLE16)NULL},
57 { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE32)NULL, 0, &ClipFormats[11], &ClipFormats[13] , (HANDLE16)NULL},
58 { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE32)NULL, 0, &ClipFormats[12], &ClipFormats[14] , (HANDLE16)NULL},
59 { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE32)NULL, 0, &ClipFormats[13], &ClipFormats[15] , (HANDLE16)NULL},
60 { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE32)NULL, 0, &ClipFormats[14], NULL , (HANDLE16)NULL}
63 static LPCLIPFORMAT __lookup_format( LPCLIPFORMAT lpFormat, WORD wID )
65 while(TRUE)
67 if (lpFormat == NULL ||
68 lpFormat->wFormatID == wID) break;
69 lpFormat = lpFormat->NextFormat;
71 return lpFormat;
75 /**************************************************************************
76 * CLIPBOARD_GetDriver
78 CLIPBOARD_DRIVER *CLIPBOARD_GetDriver()
80 #ifndef X_DISPLAY_MISSING
81 return &X11DRV_CLIPBOARD_Driver;
82 #else /* X_DISPLAY_MISSING */
83 return &TTYDRV_CLIPBOARD_Driver;
84 #endif /* X_DISPLAY_MISSING */
87 /**************************************************************************
88 * CLIPBOARD_ResetLock
90 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent, HQUEUE16 hqNew )
92 if( hqClipLock == hqCurrent )
94 if( hqNew )
95 hqClipLock = hqNew;
96 else
98 hWndClipOwner = 0;
99 hWndClipWindow = 0;
100 EmptyClipboard32();
101 hqClipLock = 0;
107 /**************************************************************************
108 * CLIPBOARD_DeleteRecord
110 void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat, BOOL32 bChange)
112 if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
113 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP )
115 if (lpFormat->hData32)
116 DeleteObject32(lpFormat->hData32);
117 if (lpFormat->hData16)
118 DeleteObject16(lpFormat->hData16);
120 else if( lpFormat->wFormatID == CF_METAFILEPICT )
122 if (lpFormat->hData32)
124 DeleteMetaFile32( ((METAFILEPICT32 *)GlobalLock32( lpFormat->hData32 ))->hMF );
125 GlobalFree32(lpFormat->hData32);
126 if (lpFormat->hData16)
127 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
128 and a shallow copy is enough to share a METAFILEPICT
129 structure between 16bit and 32bit clipboards. The MetaFile
130 should of course only be deleted once. */
131 GlobalFree16(lpFormat->hData16);
133 else if (lpFormat->hData16)
135 DeleteMetaFile16( ((METAFILEPICT16 *)GlobalLock16( lpFormat->hData16 ))->hMF );
136 GlobalFree16(lpFormat->hData16);
139 else
141 if (lpFormat->hData32)
142 GlobalFree32(lpFormat->hData32);
143 if (lpFormat->hData16)
144 GlobalFree16(lpFormat->hData16);
147 lpFormat->wDataPresent = 0;
148 lpFormat->hData16 = 0;
149 lpFormat->hData32 = 0;
151 if( bChange ) bCBHasChanged = TRUE;
154 /**************************************************************************
155 * CLIPBOARD_IsPresent
157 BOOL32 CLIPBOARD_IsPresent(WORD wFormat)
159 /* special case */
161 if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
162 return ClipFormats[CF_TEXT-1].wDataPresent ||
163 ClipFormats[CF_OEMTEXT-1].wDataPresent;
164 else
166 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
167 if( lpFormat ) return (lpFormat->wDataPresent);
169 return FALSE;
172 /**************************************************************************
173 * OpenClipboard16 (USER.137)
175 BOOL16 WINAPI OpenClipboard16( HWND16 hWnd )
177 return OpenClipboard32( hWnd );
181 /**************************************************************************
182 * OpenClipboard32 (USER32.407)
184 * Note: Netscape uses NULL hWnd to open the clipboard.
186 BOOL32 WINAPI OpenClipboard32( HWND32 hWnd )
188 BOOL32 bRet;
190 TRACE(clipboard,"(%04x)...\n", hWnd);
192 if (!hqClipLock)
194 hqClipLock = GetFastQueue();
195 hWndClipWindow = hWnd;
196 bCBHasChanged = FALSE;
197 bRet = TRUE;
199 else bRet = FALSE;
201 TRACE(clipboard," returning %i\n", bRet);
202 return bRet;
206 /**************************************************************************
207 * CloseClipboard16 (USER.138)
209 BOOL16 WINAPI CloseClipboard16(void)
211 return CloseClipboard32();
215 /**************************************************************************
216 * CloseClipboard32 (USER32.54)
218 BOOL32 WINAPI CloseClipboard32(void)
220 TRACE(clipboard,"!\n");
222 if (hqClipLock == GetFastQueue())
224 hWndClipWindow = 0;
226 if (bCBHasChanged && hWndViewer)
227 SendMessage16(hWndViewer, WM_DRAWCLIPBOARD, 0, 0L);
228 hqClipLock = 0;
230 return TRUE;
234 /**************************************************************************
235 * EmptyClipboard16 (USER.139)
237 BOOL16 WINAPI EmptyClipboard16(void)
239 return EmptyClipboard32();
243 /**************************************************************************
244 * EmptyClipboard32 (USER32.169)
246 BOOL32 WINAPI EmptyClipboard32(void)
248 LPCLIPFORMAT lpFormat = ClipFormats;
250 TRACE(clipboard,"(void)\n");
252 if (hqClipLock != GetFastQueue()) return FALSE;
254 /* destroy private objects */
256 if (hWndClipOwner)
257 SendMessage16(hWndClipOwner, WM_DESTROYCLIPBOARD, 0, 0L);
259 while(lpFormat)
261 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
262 CLIPBOARD_DeleteRecord( lpFormat, TRUE );
264 lpFormat = lpFormat->NextFormat;
267 hWndClipOwner = hWndClipWindow;
269 CLIPBOARD_GetDriver()->pEmptyClipboard();
271 return TRUE;
275 /**************************************************************************
276 * GetClipboardOwner16 (USER.140)
278 HWND16 WINAPI GetClipboardOwner16(void)
280 return hWndClipOwner;
284 /**************************************************************************
285 * GetClipboardOwner32 (USER32.225)
287 HWND32 WINAPI GetClipboardOwner32(void)
289 return hWndClipOwner;
293 /**************************************************************************
294 * SetClipboardData16 (USER.141)
296 HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
298 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
300 TRACE(clipboard, "(%04X, %04x) !\n", wFormat, hData);
302 /* NOTE: If the hData is zero and current owner doesn't match
303 * the window that opened the clipboard then this application
304 * is screwed because WM_RENDERFORMAT will go to the owner
305 * (to become the owner it must call EmptyClipboard() before
306 * adding new data).
309 if( (hqClipLock != GetFastQueue()) || !lpFormat ||
310 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
312 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
314 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
316 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
318 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
320 if( wFormat == CF_TEXT
321 && ( ClipFormats[CF_OEMTEXT-1].hData16
322 || ClipFormats[CF_OEMTEXT-1].hData32 )
323 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
324 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
325 if( wFormat == CF_OEMTEXT
326 && ( ClipFormats[CF_OEMTEXT-1].hData16
327 || ClipFormats[CF_OEMTEXT-1].hData32 )
328 && !ClipFormats[CF_TEXT-1].wDataPresent )
329 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
332 bCBHasChanged = TRUE;
333 lpFormat->wDataPresent = 1;
334 lpFormat->hData16 = hData; /* 0 is legal, see WM_RENDERFORMAT */
335 lpFormat->hData32 = 0;
337 return lpFormat->hData16;
341 /**************************************************************************
342 * SetClipboardData32 (USER32.470)
344 HANDLE32 WINAPI SetClipboardData32( UINT32 wFormat, HANDLE32 hData )
346 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
348 TRACE(clipboard, "(%08X, %08x) !\n", wFormat, hData);
350 /* NOTE: If the hData is zero and current owner doesn't match
351 * the window that opened the clipboard then this application
352 * is screwed because WM_RENDERFORMAT will go to the owner
353 * (to become the owner it must call EmptyClipboard() before
354 * adding new data).
357 if( (hqClipLock != GetFastQueue()) || !lpFormat ||
358 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
360 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
362 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
364 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
366 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
368 if( wFormat == CF_TEXT
369 && ( ClipFormats[CF_OEMTEXT-1].hData16
370 || ClipFormats[CF_OEMTEXT-1].hData32 )
371 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
372 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
373 if( wFormat == CF_OEMTEXT
374 && ( ClipFormats[CF_OEMTEXT-1].hData16
375 || ClipFormats[CF_OEMTEXT-1].hData32 )
376 && !ClipFormats[CF_TEXT-1].wDataPresent )
377 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
380 bCBHasChanged = TRUE;
381 lpFormat->wDataPresent = 1;
382 lpFormat->hData32 = hData; /* 0 is legal, see WM_RENDERFORMAT */
383 lpFormat->hData16 = 0;
385 return lpFormat->hData32;
389 /**************************************************************************
390 * CLIPBOARD_RenderFormat
392 static BOOL32 CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat)
394 if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
396 if( IsWindow32(hWndClipOwner) )
397 SendMessage16(hWndClipOwner,WM_RENDERFORMAT,
398 (WPARAM16)lpFormat->wFormatID,0L);
399 else
401 WARN(clipboard, "\thWndClipOwner (%04x) is lost!\n",
402 hWndClipOwner);
403 hWndClipOwner = 0; lpFormat->wDataPresent = 0;
404 return FALSE;
407 return (lpFormat->hData16 || lpFormat->hData32) ? TRUE : FALSE;
410 /**************************************************************************
411 * CLIPBOARD_RenderText
413 * Convert text between UNIX and DOS formats.
415 static BOOL32 CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget, LPCLIPFORMAT lpSource)
417 UINT16 size;
418 LPCSTR lpstrS;
419 LPSTR lpstrT;
421 if (lpSource->hData32)
423 size = GlobalSize32( lpSource->hData32 );
424 lpstrS = (LPSTR)GlobalLock32(lpSource->hData32);
426 else
428 size = GlobalSize16( lpSource->hData16 );
429 lpstrS = (LPSTR)GlobalLock16(lpSource->hData16);
432 if( !lpstrS ) return FALSE;
433 TRACE(clipboard,"\tconverting from '%s' to '%s', %i chars\n",
434 lpSource->Name, lpTarget->Name, size);
436 lpTarget->hData32 = GlobalAlloc32(GMEM_ZEROINIT, size);
437 lpstrT = (LPSTR)GlobalLock32(lpTarget->hData32);
439 if( lpstrT )
441 if( lpSource->wFormatID == CF_TEXT )
442 CharToOemBuff32A(lpstrS, lpstrT, size);
443 else
444 OemToCharBuff32A(lpstrS, lpstrT, size);
445 TRACE(clipboard,"\tgot %s\n", lpstrT);
446 GlobalUnlock32(lpTarget->hData32);
447 if (lpSource->hData32)
448 GlobalUnlock32(lpSource->hData32);
449 else
450 GlobalUnlock16(lpSource->hData16);
451 return TRUE;
454 lpTarget->hData32 = 0;
455 if (lpSource->hData32)
456 GlobalUnlock32(lpSource->hData32);
457 else
458 GlobalUnlock16(lpSource->hData16);
459 return FALSE;
462 /**************************************************************************
463 * GetClipboardData16 (USER.142)
465 HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat )
467 LPCLIPFORMAT lpRender = ClipFormats;
468 LPCLIPFORMAT lpUpdate = NULL;
470 if (hqClipLock != GetFastQueue()) return 0;
472 TRACE(clipboard,"(%04X)\n", wFormat);
474 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
475 && lpRender[CF_OEMTEXT-1].wDataPresent )
477 lpRender = &ClipFormats[CF_OEMTEXT-1];
478 lpUpdate = &ClipFormats[CF_TEXT-1];
480 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
482 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
483 && lpRender[CF_TEXT-1].wDataPresent )
485 lpRender = &ClipFormats[CF_TEXT-1];
486 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
488 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
490 else
492 lpRender = __lookup_format( ClipFormats, wFormat );
493 lpUpdate = lpRender;
496 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
497 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
498 CLIPBOARD_RenderText(lpUpdate, lpRender);
500 if( lpUpdate->hData32 && !lpUpdate->hData16 )
502 int size;
503 if( lpUpdate->wFormatID == CF_METAFILEPICT )
504 size = sizeof( METAFILEPICT16 );
505 else
506 size = GlobalSize32(lpUpdate->hData32);
507 lpUpdate->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
508 if( !lpUpdate->hData16 )
509 ERR(clipboard, "(%04X) -- not enough memory in 16b heap\n", wFormat);
510 else
512 if( lpUpdate->wFormatID == CF_METAFILEPICT )
514 FIXME(clipboard,"\timplement function CopyMetaFilePict32to16\n");
515 FIXME(clipboard,"\tin the appropriate file.\n");
516 #ifdef SOMEONE_IMPLEMENTED_ME
517 CopyMetaFilePict32to16( GlobalLock16(lpUpdate->hData16),
518 GlobalLock32(lpUpdate->hData32) );
519 #endif
521 else
523 memcpy( GlobalLock16(lpUpdate->hData16),
524 GlobalLock32(lpUpdate->hData32),
525 size );
527 GlobalUnlock16(lpUpdate->hData16);
528 GlobalUnlock32(lpUpdate->hData32);
532 TRACE(clipboard,"\treturning %04x (type %i)\n",
533 lpUpdate->hData16, lpUpdate->wFormatID);
534 return lpUpdate->hData16;
538 /**************************************************************************
539 * GetClipboardData32 (USER32.222)
541 HANDLE32 WINAPI GetClipboardData32( UINT32 wFormat )
543 LPCLIPFORMAT lpRender = ClipFormats;
544 LPCLIPFORMAT lpUpdate = NULL;
546 if (hqClipLock != GetFastQueue()) return 0;
548 TRACE(clipboard,"(%08X)\n", wFormat);
550 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
551 && lpRender[CF_OEMTEXT-1].wDataPresent )
553 lpRender = &ClipFormats[CF_OEMTEXT-1];
554 lpUpdate = &ClipFormats[CF_TEXT-1];
556 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
558 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
559 && lpRender[CF_TEXT-1].wDataPresent )
561 lpRender = &ClipFormats[CF_TEXT-1];
562 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
564 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
566 else
568 lpRender = __lookup_format( ClipFormats, wFormat );
569 lpUpdate = lpRender;
572 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
573 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
574 CLIPBOARD_RenderText(lpUpdate, lpRender);
576 if( lpUpdate->hData16 && !lpUpdate->hData32 )
578 int size;
579 if( lpUpdate->wFormatID == CF_METAFILEPICT )
580 size = sizeof( METAFILEPICT32 );
581 else
582 size = GlobalSize16(lpUpdate->hData16);
583 lpUpdate->hData32 = GlobalAlloc32(GMEM_ZEROINIT, size);
584 if( lpUpdate->wFormatID == CF_METAFILEPICT )
586 FIXME(clipboard,"\timplement function CopyMetaFilePict16to32\n");
587 FIXME(clipboard,"\tin the appropriate file.\n");
588 #ifdef SOMEONE_IMPLEMENTED_ME
589 CopyMetaFilePict16to32( GlobalLock16(lpUpdate->hData32),
590 GlobalLock32(lpUpdate->hData16) );
591 #endif
593 else
595 memcpy( GlobalLock32(lpUpdate->hData32),
596 GlobalLock16(lpUpdate->hData16),
597 size );
599 GlobalUnlock32(lpUpdate->hData32);
600 GlobalUnlock16(lpUpdate->hData16);
603 TRACE(clipboard,"\treturning %04x (type %i)\n",
604 lpUpdate->hData32, lpUpdate->wFormatID);
605 return lpUpdate->hData32;
608 /**************************************************************************
609 * CountClipboardFormats16 (USER.143)
611 INT16 WINAPI CountClipboardFormats16(void)
613 return CountClipboardFormats32();
617 /**************************************************************************
618 * CountClipboardFormats32 (USER32.63)
620 INT32 WINAPI CountClipboardFormats32(void)
622 INT32 FormatCount = 0;
623 LPCLIPFORMAT lpFormat = ClipFormats;
625 TRACE(clipboard,"(void)\n");
627 /* FIXME: Returns BOOL32 */
628 CLIPBOARD_GetDriver()->pRequestSelection();
630 FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
631 lpFormat[CF_OEMTEXT-1].wDataPresent);
633 while(TRUE)
635 if (lpFormat == NULL) break;
636 if (lpFormat->wDataPresent)
638 TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
639 FormatCount++;
641 lpFormat = lpFormat->NextFormat;
644 TRACE(clipboard,"\ttotal %d\n", FormatCount);
645 return FormatCount;
649 /**************************************************************************
650 * EnumClipboardFormats16 (USER.144)
652 UINT16 WINAPI EnumClipboardFormats16( UINT16 wFormat )
654 return EnumClipboardFormats32( wFormat );
658 /**************************************************************************
659 * EnumClipboardFormats32 (USER32.179)
661 UINT32 WINAPI EnumClipboardFormats32( UINT32 wFormat )
663 LPCLIPFORMAT lpFormat = ClipFormats;
665 TRACE(clipboard,"(%04X)\n", wFormat);
667 if( hqClipLock != GetFastQueue() ) return 0;
669 if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
670 CLIPBOARD_GetDriver()->pRequestSelection();
672 if (wFormat == 0)
674 if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent)
675 return lpFormat->wFormatID;
676 else
677 wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
680 /* walk up to the specified format record */
682 if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) return 0;
684 /* find next format with available data */
686 lpFormat = lpFormat->NextFormat;
687 while(TRUE)
689 if (lpFormat == NULL) return 0;
690 if (lpFormat->wDataPresent || (lpFormat->wFormatID == CF_OEMTEXT &&
691 ClipFormats[CF_TEXT-1].wDataPresent))
692 break;
693 lpFormat = lpFormat->NextFormat;
696 return lpFormat->wFormatID;
700 /**************************************************************************
701 * RegisterClipboardFormat16 (USER.145)
703 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR FormatName )
705 LPCLIPFORMAT lpNewFormat;
706 LPCLIPFORMAT lpFormat = ClipFormats;
708 if (FormatName == NULL) return 0;
710 TRACE(clipboard,"('%s') !\n", FormatName);
712 /* walk format chain to see if it's already registered */
714 while(TRUE)
716 if ( !strcmp(lpFormat->Name,FormatName) )
718 lpFormat->wRefCount++;
719 return lpFormat->wFormatID;
722 if ( lpFormat->NextFormat == NULL ) break;
724 lpFormat = lpFormat->NextFormat;
727 /* allocate storage for new format entry */
729 lpNewFormat = (LPCLIPFORMAT)xmalloc(sizeof(CLIPFORMAT));
730 lpFormat->NextFormat = lpNewFormat;
731 lpNewFormat->wFormatID = LastRegFormat;
732 lpNewFormat->wRefCount = 1;
734 lpNewFormat->Name = (LPSTR)xmalloc(strlen(FormatName) + 1);
735 strcpy(lpNewFormat->Name, FormatName);
737 lpNewFormat->wDataPresent = 0;
738 lpNewFormat->hData16 = 0;
739 lpNewFormat->hData32 = 0;
740 lpNewFormat->BufSize = 0;
741 lpNewFormat->PrevFormat = lpFormat;
742 lpNewFormat->NextFormat = NULL;
744 return LastRegFormat++;
748 /**************************************************************************
749 * RegisterClipboardFormat32A (USER32.431)
751 UINT32 WINAPI RegisterClipboardFormat32A( LPCSTR formatName )
753 return RegisterClipboardFormat16( formatName );
757 /**************************************************************************
758 * RegisterClipboardFormat32W (USER32.432)
760 UINT32 WINAPI RegisterClipboardFormat32W( LPCWSTR formatName )
762 LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
763 UINT32 ret = RegisterClipboardFormat32A( aFormat );
764 HeapFree( GetProcessHeap(), 0, aFormat );
765 return ret;
768 /**************************************************************************
769 * GetClipboardFormatName16 (USER.146)
771 INT16 WINAPI GetClipboardFormatName16( UINT16 wFormat, LPSTR retStr, INT16 maxlen )
773 return GetClipboardFormatName32A( wFormat, retStr, maxlen );
777 /**************************************************************************
778 * GetClipboardFormatName32A (USER32.223)
780 INT32 WINAPI GetClipboardFormatName32A( UINT32 wFormat, LPSTR retStr, INT32 maxlen )
782 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
784 TRACE(clipboard, "(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
786 if (lpFormat == NULL || lpFormat->Name == NULL ||
787 lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
789 TRACE(clipboard, "Name='%s' !\n", lpFormat->Name);
791 lstrcpyn32A( retStr, lpFormat->Name, maxlen );
792 return strlen(retStr);
796 /**************************************************************************
797 * GetClipboardFormatName32W (USER32.224)
799 INT32 WINAPI GetClipboardFormatName32W( UINT32 wFormat, LPWSTR retStr, INT32 maxlen )
801 LPSTR p = HEAP_xalloc( GetProcessHeap(), 0, maxlen );
802 INT32 ret = GetClipboardFormatName32A( wFormat, p, maxlen );
803 lstrcpynAtoW( retStr, p, maxlen );
804 HeapFree( GetProcessHeap(), 0, p );
805 return ret;
809 /**************************************************************************
810 * SetClipboardViewer16 (USER.147)
812 HWND16 WINAPI SetClipboardViewer16( HWND16 hWnd )
814 return SetClipboardViewer32( hWnd );
818 /**************************************************************************
819 * SetClipboardViewer32 (USER32.471)
821 HWND32 WINAPI SetClipboardViewer32( HWND32 hWnd )
823 HWND32 hwndPrev = hWndViewer;
825 TRACE(clipboard,"(%04x): returning %04x\n", hWnd, hwndPrev);
827 hWndViewer = hWnd;
828 return hwndPrev;
832 /**************************************************************************
833 * GetClipboardViewer16 (USER.148)
835 HWND16 WINAPI GetClipboardViewer16(void)
837 return hWndViewer;
841 /**************************************************************************
842 * GetClipboardViewer32 (USER32.226)
844 HWND32 WINAPI GetClipboardViewer32(void)
846 return hWndViewer;
850 /**************************************************************************
851 * ChangeClipboardChain16 (USER.149)
853 BOOL16 WINAPI ChangeClipboardChain16(HWND16 hWnd, HWND16 hWndNext)
855 return ChangeClipboardChain32(hWnd, hWndNext);
858 /**************************************************************************
859 * ChangeClipboardChain32 (USER32.22)
861 BOOL32 WINAPI ChangeClipboardChain32(HWND32 hWnd, HWND32 hWndNext)
863 BOOL32 bRet = 0;
865 FIXME(clipboard, "(0x%04x, 0x%04x): stub?\n", hWnd, hWndNext);
867 if( hWndViewer )
868 bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
869 (WPARAM16)hWnd, (LPARAM)hWndNext);
870 else
871 WARN(clipboard, "hWndViewer is lost\n");
873 if( hWnd == hWndViewer ) hWndViewer = hWndNext;
875 return bRet;
880 /**************************************************************************
881 * IsClipboardFormatAvailable16 (USER.193)
883 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
885 return IsClipboardFormatAvailable32( wFormat );
889 /**************************************************************************
890 * IsClipboardFormatAvailable32 (USER32.340)
892 BOOL32 WINAPI IsClipboardFormatAvailable32( UINT32 wFormat )
894 TRACE(clipboard,"(%04X) !\n", wFormat);
896 if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
897 CLIPBOARD_GetDriver()->pRequestSelection();
899 return CLIPBOARD_IsPresent(wFormat);
903 /**************************************************************************
904 * GetOpenClipboardWindow16 (USER.248)
906 HWND16 WINAPI GetOpenClipboardWindow16(void)
908 return hWndClipWindow;
912 /**************************************************************************
913 * GetOpenClipboardWindow32 (USER32.277)
915 HWND32 WINAPI GetOpenClipboardWindow32(void)
917 return hWndClipWindow;
921 /**************************************************************************
922 * GetPriorityClipboardFormat16 (USER.402)
924 INT16 WINAPI GetPriorityClipboardFormat16( UINT16 *lpPriorityList, INT16 nCount)
926 FIXME(clipboard, "(%p,%d): stub\n", lpPriorityList, nCount );
927 return 0;
931 /**************************************************************************
932 * GetPriorityClipboardFormat32 (USER32.279)
934 INT32 WINAPI GetPriorityClipboardFormat32( UINT32 *lpPriorityList, INT32 nCount )
936 int Counter;
938 if(CountClipboardFormats32() == 0)
940 return 0;
943 for(Counter = 0; Counter <= nCount; Counter++)
945 if(IsClipboardFormatAvailable32(*(lpPriorityList+sizeof(INT32)*Counter)))
946 return *(lpPriorityList+sizeof(INT32)*Counter);
949 return -1;