fdopen: don't rewind the file after creating the FILE* handle. Added
[wine] / dlls / shell32 / clipboard.c
1 /*
2  *      clipboard helper functions
3  *
4  *      Copyright 2000  Juergen Schmied <juergen.schmied@debitel.de>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * NOTES:
21  *
22  * For copy & paste functions within contextmenus does the shell use
23  * the OLE clipboard functions in combination with dataobjects.
24  * The OLE32.DLL gets loaded with LoadLibrary
25  *
26  * - a right mousebutton-copy sets the following formats:
27  *  classic:
28  *      Shell IDList Array
29  *      Prefered Drop Effect
30  *      Shell Object Offsets
31  *      HDROP
32  *      FileName
33  *  ole:
34  *      OlePrivateData (ClipboardDataObjectInterface)
35  *
36  */
37
38 #include <string.h>
39
40 #include "winreg.h"
41 #include "pidl.h"
42 #include "undocshell.h"
43 #include "shell32_main.h"
44 #include "shlwapi.h"
45
46 #include "wine/debug.h"
47
48 WINE_DEFAULT_DEBUG_CHANNEL(shell);
49
50 HRESULT (WINAPI *pOleInitialize)(LPVOID reserved);
51 void    (WINAPI *pOleUninitialize)(void);
52 HRESULT (WINAPI *pRegisterDragDrop)(HWND hwnd, IDropTarget* pDropTarget);
53 HRESULT (WINAPI *pRevokeDragDrop)(HWND hwnd);
54 HRESULT (WINAPI *pDoDragDrop)(LPDATAOBJECT,LPDROPSOURCE,DWORD,DWORD*);
55 void    (WINAPI *pReleaseStgMedium)(STGMEDIUM* pmedium);
56 HRESULT (WINAPI *pOleSetClipboard)(IDataObject* pDataObj);
57 HRESULT (WINAPI *pOleGetClipboard)(IDataObject** ppDataObj);
58
59 /**************************************************************************
60  * GetShellOle
61  *
62  * make sure OLE32.DLL is loaded
63  */
64 BOOL GetShellOle(void)
65 {
66         if(!hShellOle32)
67         {
68           hShellOle32 = LoadLibraryA("ole32.dll");
69           if(hShellOle32)
70           {
71             pOleInitialize=(void*)GetProcAddress(hShellOle32,"OleInitialize");
72             pOleUninitialize=(void*)GetProcAddress(hShellOle32,"OleUninitialize");
73             pRegisterDragDrop=(void*)GetProcAddress(hShellOle32,"RegisterDragDrop");
74             pRevokeDragDrop=(void*)GetProcAddress(hShellOle32,"RevokeDragDrop");
75             pDoDragDrop=(void*)GetProcAddress(hShellOle32,"DoDragDrop");
76             pReleaseStgMedium=(void*)GetProcAddress(hShellOle32,"ReleaseStgMedium");
77             pOleSetClipboard=(void*)GetProcAddress(hShellOle32,"OleSetClipboard");
78             pOleGetClipboard=(void*)GetProcAddress(hShellOle32,"OleGetClipboard");
79
80             pOleInitialize(NULL);
81           }
82         }
83         return TRUE;
84 }
85
86 /**************************************************************************
87  * RenderHDROP
88  *
89  * creates a CF_HDROP structure
90  */
91 HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
92 {
93         UINT i;
94         int rootsize = 0,size = 0;
95         char szRootPath[MAX_PATH];
96         char szFileName[MAX_PATH];
97         HGLOBAL hGlobal;
98         DROPFILES *pDropFiles;
99         int offset;
100
101         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
102
103         /* get the size needed */
104         size = sizeof(DROPFILES);
105
106         SHGetPathFromIDListA(pidlRoot, szRootPath);
107         PathAddBackslashA(szRootPath);
108         rootsize = strlen(szRootPath);
109
110         for (i=0; i<cidl;i++)
111         {
112           _ILSimpleGetText(apidl[i], szFileName, MAX_PATH);
113           size += rootsize + strlen(szFileName) + 1;
114         }
115
116         size++;
117
118         /* Fill the structure */
119         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
120         if(!hGlobal) return hGlobal;
121
122         pDropFiles = (DROPFILES *)GlobalLock(hGlobal);
123         pDropFiles->pFiles = sizeof(DROPFILES);
124         pDropFiles->fWide = FALSE;
125
126         offset = pDropFiles->pFiles;
127         strcpy(szFileName, szRootPath);
128
129         for (i=0; i<cidl;i++)
130         {
131
132           _ILSimpleGetText(apidl[i], szFileName + rootsize, MAX_PATH - rootsize);
133           size = strlen(szFileName) + 1;
134           strcpy(((char*)pDropFiles)+offset, szFileName);
135           offset += size;
136         }
137
138         ((char*)pDropFiles)[offset] = 0;
139         GlobalUnlock(hGlobal);
140
141         return hGlobal;
142 }
143
144 HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
145 {
146         UINT i;
147         int offset = 0, sizePidl, size;
148         HGLOBAL hGlobal;
149         LPIDA   pcida;
150
151         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
152
153         /* get the size needed */
154         size = sizeof(CIDA) + sizeof (UINT)*(cidl);     /* header */
155         size += ILGetSize (pidlRoot);                   /* root pidl */
156         for(i=0; i<cidl; i++)
157         {
158           size += ILGetSize(apidl[i]);                  /* child pidls */
159         }
160
161         /* fill the structure */
162         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
163         if(!hGlobal) return hGlobal;
164         pcida = GlobalLock (hGlobal);
165         pcida->cidl = cidl;
166
167         /* root pidl */
168         offset = sizeof(CIDA) + sizeof (UINT)*(cidl);
169         pcida->aoffset[0] = offset;                     /* first element */
170         sizePidl = ILGetSize (pidlRoot);
171         memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl);
172         offset += sizePidl;
173
174         for(i=0; i<cidl; i++)                           /* child pidls */
175         {
176           pcida->aoffset[i+1] = offset;
177           sizePidl = ILGetSize(apidl[i]);
178           memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl);
179           offset += sizePidl;
180         }
181
182         GlobalUnlock(hGlobal);
183         return hGlobal;
184 }
185
186 HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
187 {
188         FIXME("\n");
189         return 0;
190 }
191
192 HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
193 {
194         FIXME("\n");
195         return 0;
196 }
197
198 HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
199 {
200         FIXME("\n");
201         return 0;
202 }
203
204 HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
205 {
206         int len, size = 0;
207         char szTemp[MAX_PATH], *szFileName;
208         HGLOBAL hGlobal;
209
210         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
211
212         /* build name of first file */
213         SHGetPathFromIDListA(pidlRoot, szTemp);
214         PathAddBackslashA(szTemp);
215         len = strlen(szTemp);
216         _ILSimpleGetText(apidl[0], szTemp+len, MAX_PATH - len);
217         size = strlen(szTemp) + 1;
218
219         /* fill the structure */
220         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
221         if(!hGlobal) return hGlobal;
222         szFileName = (char *)GlobalLock(hGlobal);
223         GlobalUnlock(hGlobal);
224         return hGlobal;
225 }
226
227 HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags)
228 {
229         DWORD * pdwFlag;
230         HGLOBAL hGlobal;
231
232         TRACE("(0x%08lx)\n", dwFlags);
233
234         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
235         if(!hGlobal) return hGlobal;
236         pdwFlag = (DWORD*)GlobalLock(hGlobal);
237         *pdwFlag = dwFlags;
238         GlobalUnlock(hGlobal);
239         return hGlobal;
240 }
241
242 /**************************************************************************
243  * IsDataInClipboard
244  *
245  * checks if there is something in the clipboard we can use
246  */
247 BOOL IsDataInClipboard (HWND hwnd)
248 {
249         BOOL ret = FALSE;
250
251         if (OpenClipboard(hwnd))
252         {
253           if (GetOpenClipboardWindow())
254           {
255             ret = IsClipboardFormatAvailable(CF_TEXT);
256           }
257           CloseClipboard();
258         }
259         return ret;
260 }