Handle non-hardware X events correctly with native USER
[wine/multimedia.git] / windows / clipboard.c
blob99382f9adcf33ae92174a106c04fac31cba901f1
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 "windows.h"
16 #include "win.h"
17 #include "heap.h"
18 #include "message.h"
19 #include "clipboard.h"
20 #include "xmalloc.h"
21 #include "debug.h"
23 extern CLIPBOARD_DRIVER X11DRV_CLIPBOARD_Driver;
25 #define CF_REGFORMATBASE 0xC000
27 /**************************************************************************
28 * internal variables
31 static HQUEUE16 hqClipLock = 0;
32 static BOOL32 bCBHasChanged = FALSE;
34 HWND32 hWndClipOwner = 0; /* current clipboard owner */
35 HWND32 hWndClipWindow = 0; /* window that opened clipboard */
36 static HWND32 hWndViewer = 0; /* start of viewers chain */
38 static WORD LastRegFormat = CF_REGFORMATBASE;
40 CLIPFORMAT ClipFormats[16] = {
41 { CF_TEXT, 1, 0, "Text", (HANDLE32)NULL, 0, NULL, &ClipFormats[1] , (HANDLE16)NULL},
42 { CF_BITMAP, 1, 0, "Bitmap", (HANDLE32)NULL, 0, &ClipFormats[0], &ClipFormats[2] , (HANDLE16)NULL},
43 { CF_METAFILEPICT, 1, 0, "MetaFile Picture", (HANDLE32)NULL, 0, &ClipFormats[1], &ClipFormats[3] , (HANDLE16)NULL},
44 { CF_SYLK, 1, 0, "Sylk", (HANDLE32)NULL, 0, &ClipFormats[2], &ClipFormats[4] , (HANDLE16)NULL},
45 { CF_DIF, 1, 0, "DIF", (HANDLE32)NULL, 0, &ClipFormats[3], &ClipFormats[5] , (HANDLE16)NULL},
46 { CF_TIFF, 1, 0, "TIFF", (HANDLE32)NULL, 0, &ClipFormats[4], &ClipFormats[6] , (HANDLE16)NULL},
47 { CF_OEMTEXT, 1, 0, "OEM Text", (HANDLE32)NULL, 0, &ClipFormats[5], &ClipFormats[7] , (HANDLE16)NULL},
48 { CF_DIB, 1, 0, "DIB", (HANDLE32)NULL, 0, &ClipFormats[6], &ClipFormats[8] , (HANDLE16)NULL},
49 { CF_PALETTE, 1, 0, "Palette", (HANDLE32)NULL, 0, &ClipFormats[7], &ClipFormats[9] , (HANDLE16)NULL},
50 { CF_PENDATA, 1, 0, "PenData", (HANDLE32)NULL, 0, &ClipFormats[8], &ClipFormats[10] , (HANDLE16)NULL},
51 { CF_RIFF, 1, 0, "RIFF", (HANDLE32)NULL, 0, &ClipFormats[9], &ClipFormats[11] , (HANDLE16)NULL},
52 { CF_WAVE, 1, 0, "Wave", (HANDLE32)NULL, 0, &ClipFormats[10], &ClipFormats[12] , (HANDLE16)NULL},
53 { CF_OWNERDISPLAY, 1, 0, "Owner Display", (HANDLE32)NULL, 0, &ClipFormats[11], &ClipFormats[13] , (HANDLE16)NULL},
54 { CF_DSPTEXT, 1, 0, "DSPText", (HANDLE32)NULL, 0, &ClipFormats[12], &ClipFormats[14] , (HANDLE16)NULL},
55 { CF_DSPMETAFILEPICT, 1, 0, "DSPMetaFile Picture", (HANDLE32)NULL, 0, &ClipFormats[13], &ClipFormats[15] , (HANDLE16)NULL},
56 { CF_DSPBITMAP, 1, 0, "DSPBitmap", (HANDLE32)NULL, 0, &ClipFormats[14], NULL , (HANDLE16)NULL}
59 static LPCLIPFORMAT __lookup_format( LPCLIPFORMAT lpFormat, WORD wID )
61 while(TRUE)
63 if (lpFormat == NULL ||
64 lpFormat->wFormatID == wID) break;
65 lpFormat = lpFormat->NextFormat;
67 return lpFormat;
71 /**************************************************************************
72 * CLIPBOARD_GetDriver
74 CLIPBOARD_DRIVER *CLIPBOARD_GetDriver()
76 return &X11DRV_CLIPBOARD_Driver;
79 /**************************************************************************
80 * CLIPBOARD_ResetLock
82 void CLIPBOARD_ResetLock( HQUEUE16 hqCurrent, HQUEUE16 hqNew )
84 if( hqClipLock == hqCurrent )
86 if( hqNew )
87 hqClipLock = hqNew;
88 else
90 hWndClipOwner = 0;
91 hWndClipWindow = 0;
92 EmptyClipboard32();
93 hqClipLock = 0;
99 /**************************************************************************
100 * CLIPBOARD_DeleteRecord
102 void CLIPBOARD_DeleteRecord(LPCLIPFORMAT lpFormat, BOOL32 bChange)
104 if( (lpFormat->wFormatID >= CF_GDIOBJFIRST &&
105 lpFormat->wFormatID <= CF_GDIOBJLAST) || lpFormat->wFormatID == CF_BITMAP )
107 if (lpFormat->hData32)
108 DeleteObject32(lpFormat->hData32);
109 if (lpFormat->hData16)
110 DeleteObject16(lpFormat->hData16);
112 else if( lpFormat->wFormatID == CF_METAFILEPICT )
114 if (lpFormat->hData32)
116 DeleteMetaFile32( ((METAFILEPICT32 *)GlobalLock32( lpFormat->hData32 ))->hMF );
117 GlobalFree32(lpFormat->hData32);
118 if (lpFormat->hData16)
119 /* HMETAFILE16 and HMETAFILE32 are apparently the same thing,
120 and a shallow copy is enough to share a METAFILEPICT
121 structure between 16bit and 32bit clipboards. The MetaFile
122 should of course only be deleted once. */
123 GlobalFree16(lpFormat->hData16);
125 else if (lpFormat->hData16)
127 DeleteMetaFile16( ((METAFILEPICT16 *)GlobalLock16( lpFormat->hData16 ))->hMF );
128 GlobalFree16(lpFormat->hData16);
131 else
133 if (lpFormat->hData32)
134 GlobalFree32(lpFormat->hData32);
135 if (lpFormat->hData16)
136 GlobalFree16(lpFormat->hData16);
139 lpFormat->wDataPresent = 0;
140 lpFormat->hData16 = 0;
141 lpFormat->hData32 = 0;
143 if( bChange ) bCBHasChanged = TRUE;
146 /**************************************************************************
147 * CLIPBOARD_IsPresent
149 BOOL32 CLIPBOARD_IsPresent(WORD wFormat)
151 /* special case */
153 if( wFormat == CF_TEXT || wFormat == CF_OEMTEXT )
154 return ClipFormats[CF_TEXT-1].wDataPresent ||
155 ClipFormats[CF_OEMTEXT-1].wDataPresent;
156 else
158 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
159 if( lpFormat ) return (lpFormat->wDataPresent);
161 return FALSE;
164 /**************************************************************************
165 * OpenClipboard16 (USER.137)
167 BOOL16 WINAPI OpenClipboard16( HWND16 hWnd )
169 return OpenClipboard32( hWnd );
173 /**************************************************************************
174 * OpenClipboard32 (USER32.407)
176 * Note: Netscape uses NULL hWnd to open the clipboard.
178 BOOL32 WINAPI OpenClipboard32( HWND32 hWnd )
180 BOOL32 bRet;
182 TRACE(clipboard,"(%04x)...\n", hWnd);
184 if (!hqClipLock)
186 hqClipLock = GetTaskQueue(0);
187 hWndClipWindow = hWnd;
188 bCBHasChanged = FALSE;
189 bRet = TRUE;
191 else bRet = FALSE;
193 TRACE(clipboard," returning %i\n", bRet);
194 return bRet;
198 /**************************************************************************
199 * CloseClipboard16 (USER.138)
201 BOOL16 WINAPI CloseClipboard16(void)
203 return CloseClipboard32();
207 /**************************************************************************
208 * CloseClipboard32 (USER32.54)
210 BOOL32 WINAPI CloseClipboard32(void)
212 TRACE(clipboard,"!\n");
214 if (hqClipLock == GetTaskQueue(0))
216 hWndClipWindow = 0;
218 if (bCBHasChanged && hWndViewer)
219 SendMessage16(hWndViewer, WM_DRAWCLIPBOARD, 0, 0L);
220 hqClipLock = 0;
222 return TRUE;
226 /**************************************************************************
227 * EmptyClipboard16 (USER.139)
229 BOOL16 WINAPI EmptyClipboard16(void)
231 return EmptyClipboard32();
235 /**************************************************************************
236 * EmptyClipboard32 (USER32.169)
238 BOOL32 WINAPI EmptyClipboard32(void)
240 LPCLIPFORMAT lpFormat = ClipFormats;
242 TRACE(clipboard,"(void)\n");
244 if (hqClipLock != GetTaskQueue(0)) return FALSE;
246 /* destroy private objects */
248 if (hWndClipOwner)
249 SendMessage16(hWndClipOwner, WM_DESTROYCLIPBOARD, 0, 0L);
251 while(lpFormat)
253 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
254 CLIPBOARD_DeleteRecord( lpFormat, TRUE );
256 lpFormat = lpFormat->NextFormat;
259 hWndClipOwner = hWndClipWindow;
261 CLIPBOARD_GetDriver()->pEmptyClipboard();
263 return TRUE;
267 /**************************************************************************
268 * GetClipboardOwner16 (USER.140)
270 HWND16 WINAPI GetClipboardOwner16(void)
272 return hWndClipOwner;
276 /**************************************************************************
277 * GetClipboardOwner32 (USER32.225)
279 HWND32 WINAPI GetClipboardOwner32(void)
281 return hWndClipOwner;
285 /**************************************************************************
286 * SetClipboardData16 (USER.141)
288 HANDLE16 WINAPI SetClipboardData16( UINT16 wFormat, HANDLE16 hData )
290 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
292 TRACE(clipboard, "(%04X, %04x) !\n", wFormat, hData);
294 /* NOTE: If the hData is zero and current owner doesn't match
295 * the window that opened the clipboard then this application
296 * is screwed because WM_RENDERFORMAT will go to the owner
297 * (to become the owner it must call EmptyClipboard() before
298 * adding new data).
301 if( (hqClipLock != GetTaskQueue(0)) || !lpFormat ||
302 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
304 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
306 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
308 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
310 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
312 if( wFormat == CF_TEXT
313 && ( ClipFormats[CF_OEMTEXT-1].hData16
314 || ClipFormats[CF_OEMTEXT-1].hData32 )
315 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
316 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
317 if( wFormat == CF_OEMTEXT
318 && ( ClipFormats[CF_OEMTEXT-1].hData16
319 || ClipFormats[CF_OEMTEXT-1].hData32 )
320 && !ClipFormats[CF_TEXT-1].wDataPresent )
321 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
324 bCBHasChanged = TRUE;
325 lpFormat->wDataPresent = 1;
326 lpFormat->hData16 = hData; /* 0 is legal, see WM_RENDERFORMAT */
327 lpFormat->hData32 = 0;
329 return lpFormat->hData16;
333 /**************************************************************************
334 * SetClipboardData32 (USER32.470)
336 HANDLE32 WINAPI SetClipboardData32( UINT32 wFormat, HANDLE32 hData )
338 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
340 TRACE(clipboard, "(%08X, %08x) !\n", wFormat, hData);
342 /* NOTE: If the hData is zero and current owner doesn't match
343 * the window that opened the clipboard then this application
344 * is screwed because WM_RENDERFORMAT will go to the owner
345 * (to become the owner it must call EmptyClipboard() before
346 * adding new data).
349 if( (hqClipLock != GetTaskQueue(0)) || !lpFormat ||
350 (!hData && (!hWndClipOwner || (hWndClipOwner != hWndClipWindow))) ) return 0;
352 CLIPBOARD_GetDriver()->pSetClipboardData(wFormat);
354 if ( lpFormat->wDataPresent || lpFormat->hData16 || lpFormat->hData32 )
356 CLIPBOARD_DeleteRecord(lpFormat, TRUE);
358 /* delete existing CF_TEXT/CF_OEMTEXT aliases */
360 if( wFormat == CF_TEXT
361 && ( ClipFormats[CF_OEMTEXT-1].hData16
362 || ClipFormats[CF_OEMTEXT-1].hData32 )
363 && !ClipFormats[CF_OEMTEXT-1].wDataPresent )
364 CLIPBOARD_DeleteRecord(&ClipFormats[CF_OEMTEXT-1], TRUE);
365 if( wFormat == CF_OEMTEXT
366 && ( ClipFormats[CF_OEMTEXT-1].hData16
367 || ClipFormats[CF_OEMTEXT-1].hData32 )
368 && !ClipFormats[CF_TEXT-1].wDataPresent )
369 CLIPBOARD_DeleteRecord(&ClipFormats[CF_TEXT-1], TRUE);
372 bCBHasChanged = TRUE;
373 lpFormat->wDataPresent = 1;
374 lpFormat->hData32 = hData; /* 0 is legal, see WM_RENDERFORMAT */
375 lpFormat->hData16 = 0;
377 return lpFormat->hData32;
381 /**************************************************************************
382 * CLIPBOARD_RenderFormat
384 static BOOL32 CLIPBOARD_RenderFormat(LPCLIPFORMAT lpFormat)
386 if( lpFormat->wDataPresent && !lpFormat->hData16 && !lpFormat->hData32 )
388 if( IsWindow32(hWndClipOwner) )
389 SendMessage16(hWndClipOwner,WM_RENDERFORMAT,
390 (WPARAM16)lpFormat->wFormatID,0L);
391 else
393 WARN(clipboard, "\thWndClipOwner (%04x) is lost!\n",
394 hWndClipOwner);
395 hWndClipOwner = 0; lpFormat->wDataPresent = 0;
396 return FALSE;
399 return (lpFormat->hData16 || lpFormat->hData32) ? TRUE : FALSE;
402 /**************************************************************************
403 * CLIPBOARD_RenderText
405 * Convert text between UNIX and DOS formats.
407 static BOOL32 CLIPBOARD_RenderText(LPCLIPFORMAT lpTarget, LPCLIPFORMAT lpSource)
409 UINT16 size;
410 LPCSTR lpstrS;
411 LPSTR lpstrT;
413 if (lpSource->hData32)
415 size = GlobalSize32( lpSource->hData32 );
416 lpstrS = (LPSTR)GlobalLock32(lpSource->hData32);
418 else
420 size = GlobalSize16( lpSource->hData16 );
421 lpstrS = (LPSTR)GlobalLock16(lpSource->hData16);
424 if( !lpstrS ) return FALSE;
425 TRACE(clipboard,"\tconverting from '%s' to '%s', %i chars\n",
426 lpSource->Name, lpTarget->Name, size);
428 lpTarget->hData32 = GlobalAlloc32(GMEM_ZEROINIT, size);
429 lpstrT = (LPSTR)GlobalLock32(lpTarget->hData32);
431 if( lpstrT )
433 if( lpSource->wFormatID == CF_TEXT )
434 CharToOemBuff32A(lpstrS, lpstrT, size);
435 else
436 OemToCharBuff32A(lpstrS, lpstrT, size);
437 TRACE(clipboard,"\tgot %s\n", lpstrT);
438 GlobalUnlock32(lpTarget->hData32);
439 if (lpSource->hData32)
440 GlobalUnlock32(lpSource->hData32);
441 else
442 GlobalUnlock16(lpSource->hData16);
443 return TRUE;
446 lpTarget->hData32 = 0;
447 if (lpSource->hData32)
448 GlobalUnlock32(lpSource->hData32);
449 else
450 GlobalUnlock16(lpSource->hData16);
451 return FALSE;
454 /**************************************************************************
455 * GetClipboardData16 (USER.142)
457 HANDLE16 WINAPI GetClipboardData16( UINT16 wFormat )
459 LPCLIPFORMAT lpRender = ClipFormats;
460 LPCLIPFORMAT lpUpdate = NULL;
462 if (hqClipLock != GetTaskQueue(0)) return 0;
464 TRACE(clipboard,"(%04X)\n", wFormat);
466 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
467 && lpRender[CF_OEMTEXT-1].wDataPresent )
469 lpRender = &ClipFormats[CF_OEMTEXT-1];
470 lpUpdate = &ClipFormats[CF_TEXT-1];
472 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
474 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
475 && lpRender[CF_TEXT-1].wDataPresent )
477 lpRender = &ClipFormats[CF_TEXT-1];
478 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
480 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
482 else
484 lpRender = __lookup_format( ClipFormats, wFormat );
485 lpUpdate = lpRender;
488 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
489 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
490 CLIPBOARD_RenderText(lpUpdate, lpRender);
492 if( lpUpdate->hData32 && !lpUpdate->hData16 )
494 int size;
495 if( lpUpdate->wFormatID == CF_METAFILEPICT )
496 size = sizeof( METAFILEPICT16 );
497 else
498 size = GlobalSize32(lpUpdate->hData32);
499 lpUpdate->hData16 = GlobalAlloc16(GMEM_ZEROINIT, size);
500 if( !lpUpdate->hData16 )
501 ERR(clipboard, "(%04X) -- not enough memory in 16b heap\n", wFormat);
502 else
504 if( lpUpdate->wFormatID == CF_METAFILEPICT )
506 FIXME(clipboard,"\timplement function CopyMetaFilePict32to16\n");
507 FIXME(clipboard,"\tin the appropriate file.\n");
508 #ifdef SOMEONE_IMPLEMENTED_ME
509 CopyMetaFilePict32to16( GlobalLock16(lpUpdate->hData16),
510 GlobalLock32(lpUpdate->hData32) );
511 #endif
513 else
515 memcpy( GlobalLock16(lpUpdate->hData16),
516 GlobalLock32(lpUpdate->hData32),
517 size );
519 GlobalUnlock16(lpUpdate->hData16);
520 GlobalUnlock32(lpUpdate->hData32);
524 TRACE(clipboard,"\treturning %04x (type %i)\n",
525 lpUpdate->hData16, lpUpdate->wFormatID);
526 return lpUpdate->hData16;
530 /**************************************************************************
531 * GetClipboardData32 (USER32.222)
533 HANDLE32 WINAPI GetClipboardData32( UINT32 wFormat )
535 LPCLIPFORMAT lpRender = ClipFormats;
536 LPCLIPFORMAT lpUpdate = NULL;
538 if (hqClipLock != GetTaskQueue(0)) return 0;
540 TRACE(clipboard,"(%08X)\n", wFormat);
542 if( wFormat == CF_TEXT && !lpRender[CF_TEXT-1].wDataPresent
543 && lpRender[CF_OEMTEXT-1].wDataPresent )
545 lpRender = &ClipFormats[CF_OEMTEXT-1];
546 lpUpdate = &ClipFormats[CF_TEXT-1];
548 TRACE(clipboard,"\tOEMTEXT -> TEXT\n");
550 else if( wFormat == CF_OEMTEXT && !lpRender[CF_OEMTEXT-1].wDataPresent
551 && lpRender[CF_TEXT-1].wDataPresent )
553 lpRender = &ClipFormats[CF_TEXT-1];
554 lpUpdate = &ClipFormats[CF_OEMTEXT-1];
556 TRACE(clipboard,"\tTEXT -> OEMTEXT\n");
558 else
560 lpRender = __lookup_format( ClipFormats, wFormat );
561 lpUpdate = lpRender;
564 if( !lpRender || !CLIPBOARD_RenderFormat(lpRender) ) return 0;
565 if( lpUpdate != lpRender && !lpUpdate->hData16 && !lpUpdate->hData32 )
566 CLIPBOARD_RenderText(lpUpdate, lpRender);
568 if( lpUpdate->hData16 && !lpUpdate->hData32 )
570 int size;
571 if( lpUpdate->wFormatID == CF_METAFILEPICT )
572 size = sizeof( METAFILEPICT32 );
573 else
574 size = GlobalSize16(lpUpdate->hData16);
575 lpUpdate->hData32 = GlobalAlloc32(GMEM_ZEROINIT, size);
576 if( lpUpdate->wFormatID == CF_METAFILEPICT )
578 FIXME(clipboard,"\timplement function CopyMetaFilePict16to32\n");
579 FIXME(clipboard,"\tin the appropriate file.\n");
580 #ifdef SOMEONE_IMPLEMENTED_ME
581 CopyMetaFilePict16to32( GlobalLock16(lpUpdate->hData32),
582 GlobalLock32(lpUpdate->hData16) );
583 #endif
585 else
587 memcpy( GlobalLock32(lpUpdate->hData32),
588 GlobalLock16(lpUpdate->hData16),
589 size );
591 GlobalUnlock32(lpUpdate->hData32);
592 GlobalUnlock16(lpUpdate->hData16);
595 TRACE(clipboard,"\treturning %04x (type %i)\n",
596 lpUpdate->hData32, lpUpdate->wFormatID);
597 return lpUpdate->hData32;
600 /**************************************************************************
601 * CountClipboardFormats16 (USER.143)
603 INT16 WINAPI CountClipboardFormats16(void)
605 return CountClipboardFormats32();
609 /**************************************************************************
610 * CountClipboardFormats32 (USER32.63)
612 INT32 WINAPI CountClipboardFormats32(void)
614 INT32 FormatCount = 0;
615 LPCLIPFORMAT lpFormat = ClipFormats;
617 TRACE(clipboard,"(void)\n");
619 /* FIXME: Returns BOOL32 */
620 CLIPBOARD_GetDriver()->pRequestSelection();
622 FormatCount += abs(lpFormat[CF_TEXT-1].wDataPresent -
623 lpFormat[CF_OEMTEXT-1].wDataPresent);
625 while(TRUE)
627 if (lpFormat == NULL) break;
628 if (lpFormat->wDataPresent)
630 TRACE(clipboard, "\tdata found for format %i\n", lpFormat->wFormatID);
631 FormatCount++;
633 lpFormat = lpFormat->NextFormat;
636 TRACE(clipboard,"\ttotal %d\n", FormatCount);
637 return FormatCount;
641 /**************************************************************************
642 * EnumClipboardFormats16 (USER.144)
644 UINT16 WINAPI EnumClipboardFormats16( UINT16 wFormat )
646 return EnumClipboardFormats32( wFormat );
650 /**************************************************************************
651 * EnumClipboardFormats32 (USER32.179)
653 UINT32 WINAPI EnumClipboardFormats32( UINT32 wFormat )
655 LPCLIPFORMAT lpFormat = ClipFormats;
657 TRACE(clipboard,"(%04X)\n", wFormat);
659 if( hqClipLock != GetTaskQueue(0) ) return 0;
661 if( (!wFormat || wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
662 CLIPBOARD_GetDriver()->pRequestSelection();
664 if (wFormat == 0)
666 if (lpFormat->wDataPresent || ClipFormats[CF_OEMTEXT-1].wDataPresent)
667 return lpFormat->wFormatID;
668 else
669 wFormat = lpFormat->wFormatID; /* and CF_TEXT is not available */
672 /* walk up to the specified format record */
674 if( !(lpFormat = __lookup_format( lpFormat, wFormat )) ) return 0;
676 /* find next format with available data */
678 lpFormat = lpFormat->NextFormat;
679 while(TRUE)
681 if (lpFormat == NULL) return 0;
682 if (lpFormat->wDataPresent || (lpFormat->wFormatID == CF_OEMTEXT &&
683 ClipFormats[CF_TEXT-1].wDataPresent))
684 break;
685 lpFormat = lpFormat->NextFormat;
688 return lpFormat->wFormatID;
692 /**************************************************************************
693 * RegisterClipboardFormat16 (USER.145)
695 UINT16 WINAPI RegisterClipboardFormat16( LPCSTR FormatName )
697 LPCLIPFORMAT lpNewFormat;
698 LPCLIPFORMAT lpFormat = ClipFormats;
700 if (FormatName == NULL) return 0;
702 TRACE(clipboard,"('%s') !\n", FormatName);
704 /* walk format chain to see if it's already registered */
706 while(TRUE)
708 if ( !strcmp(lpFormat->Name,FormatName) )
710 lpFormat->wRefCount++;
711 return lpFormat->wFormatID;
714 if ( lpFormat->NextFormat == NULL ) break;
716 lpFormat = lpFormat->NextFormat;
719 /* allocate storage for new format entry */
721 lpNewFormat = (LPCLIPFORMAT)xmalloc(sizeof(CLIPFORMAT));
722 lpFormat->NextFormat = lpNewFormat;
723 lpNewFormat->wFormatID = LastRegFormat;
724 lpNewFormat->wRefCount = 1;
726 lpNewFormat->Name = (LPSTR)xmalloc(strlen(FormatName) + 1);
727 strcpy(lpNewFormat->Name, FormatName);
729 lpNewFormat->wDataPresent = 0;
730 lpNewFormat->hData16 = 0;
731 lpNewFormat->hData32 = 0;
732 lpNewFormat->BufSize = 0;
733 lpNewFormat->PrevFormat = lpFormat;
734 lpNewFormat->NextFormat = NULL;
736 return LastRegFormat++;
740 /**************************************************************************
741 * RegisterClipboardFormat32A (USER32.431)
743 UINT32 WINAPI RegisterClipboardFormat32A( LPCSTR formatName )
745 return RegisterClipboardFormat16( formatName );
749 /**************************************************************************
750 * RegisterClipboardFormat32W (USER32.432)
752 UINT32 WINAPI RegisterClipboardFormat32W( LPCWSTR formatName )
754 LPSTR aFormat = HEAP_strdupWtoA( GetProcessHeap(), 0, formatName );
755 UINT32 ret = RegisterClipboardFormat32A( aFormat );
756 HeapFree( GetProcessHeap(), 0, aFormat );
757 return ret;
760 /**************************************************************************
761 * GetClipboardFormatName16 (USER.146)
763 INT16 WINAPI GetClipboardFormatName16( UINT16 wFormat, LPSTR retStr, INT16 maxlen )
765 return GetClipboardFormatName32A( wFormat, retStr, maxlen );
769 /**************************************************************************
770 * GetClipboardFormatName32A (USER32.223)
772 INT32 WINAPI GetClipboardFormatName32A( UINT32 wFormat, LPSTR retStr, INT32 maxlen )
774 LPCLIPFORMAT lpFormat = __lookup_format( ClipFormats, wFormat );
776 TRACE(clipboard, "(%04X, %p, %d) !\n", wFormat, retStr, maxlen);
778 if (lpFormat == NULL || lpFormat->Name == NULL ||
779 lpFormat->wFormatID < CF_REGFORMATBASE) return 0;
781 TRACE(clipboard, "Name='%s' !\n", lpFormat->Name);
783 lstrcpyn32A( retStr, lpFormat->Name, maxlen );
784 return strlen(retStr);
788 /**************************************************************************
789 * GetClipboardFormatName32W (USER32.224)
791 INT32 WINAPI GetClipboardFormatName32W( UINT32 wFormat, LPWSTR retStr, INT32 maxlen )
793 LPSTR p = HEAP_xalloc( GetProcessHeap(), 0, maxlen );
794 INT32 ret = GetClipboardFormatName32A( wFormat, p, maxlen );
795 lstrcpynAtoW( retStr, p, maxlen );
796 HeapFree( GetProcessHeap(), 0, p );
797 return ret;
801 /**************************************************************************
802 * SetClipboardViewer16 (USER.147)
804 HWND16 WINAPI SetClipboardViewer16( HWND16 hWnd )
806 return SetClipboardViewer32( hWnd );
810 /**************************************************************************
811 * SetClipboardViewer32 (USER32.471)
813 HWND32 WINAPI SetClipboardViewer32( HWND32 hWnd )
815 HWND32 hwndPrev = hWndViewer;
817 TRACE(clipboard,"(%04x): returning %04x\n", hWnd, hwndPrev);
819 hWndViewer = hWnd;
820 return hwndPrev;
824 /**************************************************************************
825 * GetClipboardViewer16 (USER.148)
827 HWND16 WINAPI GetClipboardViewer16(void)
829 return hWndViewer;
833 /**************************************************************************
834 * GetClipboardViewer32 (USER32.226)
836 HWND32 WINAPI GetClipboardViewer32(void)
838 return hWndViewer;
842 /**************************************************************************
843 * ChangeClipboardChain16 (USER.149)
845 BOOL16 WINAPI ChangeClipboardChain16(HWND16 hWnd, HWND16 hWndNext)
847 return ChangeClipboardChain32(hWnd, hWndNext);
850 /**************************************************************************
851 * ChangeClipboardChain32 (USER32.22)
853 BOOL32 WINAPI ChangeClipboardChain32(HWND32 hWnd, HWND32 hWndNext)
855 BOOL32 bRet = 0;
857 FIXME(clipboard, "(0x%04x, 0x%04x): stub?\n", hWnd, hWndNext);
859 if( hWndViewer )
860 bRet = !SendMessage16( hWndViewer, WM_CHANGECBCHAIN,
861 (WPARAM16)hWnd, (LPARAM)hWndNext);
862 else
863 WARN(clipboard, "hWndViewer is lost\n");
865 if( hWnd == hWndViewer ) hWndViewer = hWndNext;
867 return bRet;
872 /**************************************************************************
873 * IsClipboardFormatAvailable16 (USER.193)
875 BOOL16 WINAPI IsClipboardFormatAvailable16( UINT16 wFormat )
877 return IsClipboardFormatAvailable32( wFormat );
881 /**************************************************************************
882 * IsClipboardFormatAvailable32 (USER32.340)
884 BOOL32 WINAPI IsClipboardFormatAvailable32( UINT32 wFormat )
886 TRACE(clipboard,"(%04X) !\n", wFormat);
888 if( (wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
889 CLIPBOARD_GetDriver()->pRequestSelection();
891 return CLIPBOARD_IsPresent(wFormat);
895 /**************************************************************************
896 * GetOpenClipboardWindow16 (USER.248)
898 HWND16 WINAPI GetOpenClipboardWindow16(void)
900 return hWndClipWindow;
904 /**************************************************************************
905 * GetOpenClipboardWindow32 (USER32.277)
907 HWND32 WINAPI GetOpenClipboardWindow32(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 INT32 WINAPI GetPriorityClipboardFormat32( UINT32 *lpPriorityList, INT32 nCount )
928 int Counter;
930 if(CountClipboardFormats32() == 0)
932 return 0;
935 for(Counter = 0; Counter <= nCount; Counter++)
937 if(IsClipboardFormatAvailable32(*(lpPriorityList+sizeof(INT32)*Counter)))
938 return *(lpPriorityList+sizeof(INT32)*Counter);
941 return -1;