Store in the server all the window information accessible with
[wine] / dlls / shell32 / clipboard.c
1 /*
2  *      clipboard helper functions
3  *
4  *      Copyright 2000  Juergen Schmied <juergen.schmied@debitel.de>
5  *
6  * For copy & paste functions within contextmenus does the shell use
7  * the OLE clipboard functions in combination with dataobjects.
8  * The OLE32.DLL gets loaded with LoadLibrary
9  *
10  * - a right mousebutton-copy sets the following formats:
11  *  classic:
12  *      Shell IDList Array
13  *      Prefered Drop Effect
14  *      Shell Object Offsets
15  *      HDROP
16  *      FileName
17  *  ole:
18  *      OlePrivateData (ClipboardDataObjectInterface)
19  *
20  */
21
22 #include <string.h>
23
24 #include "debugtools.h"
25
26 #include "pidl.h"
27 #include "shlwapi.h"
28 #include "undocshell.h"
29 #include "shell32_main.h"
30
31 DEFAULT_DEBUG_CHANNEL(shell);
32
33 static int refClipCount = 0;
34 static HINSTANCE hShellOle32 = 0;
35
36 /**************************************************************************
37  * InitShellOle
38  *
39  * 
40  */
41 void InitShellOle(void)
42 {
43 }
44
45 /**************************************************************************
46  * FreeShellOle
47  *
48  * unload OLE32.DLL
49  */
50 void FreeShellOle(void)
51 {
52         if (!--refClipCount)
53         {
54           pOleUninitialize();
55           FreeLibrary(hShellOle32);
56         }
57 }
58
59 /**************************************************************************
60  * LoadShellOle
61  *
62  * make sure OLE32.DLL is loaded
63  */
64 BOOL GetShellOle(void)
65 {
66         if(!refClipCount)
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             refClipCount++;
82           }
83         }
84         return TRUE;
85 }
86
87 /**************************************************************************
88  * RenderHDROP
89  *
90  * creates a CF_HDROP structure
91  */
92 HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
93 {
94         int i;
95         int rootsize = 0,size = 0;
96         char szRootPath[MAX_PATH];
97         char szFileName[MAX_PATH];
98         HGLOBAL hGlobal;
99         DROPFILES *pDropFiles;
100         int offset;
101         
102         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
103
104         /* get the size needed */
105         size = sizeof(DROPFILES);
106
107         SHGetPathFromIDListA(pidlRoot, szRootPath);
108         PathAddBackslashA(szRootPath);
109         rootsize = strlen(szRootPath);
110         
111         for (i=0; i<cidl;i++)
112         {
113           _ILSimpleGetText(apidl[i], szFileName, MAX_PATH);
114           size += rootsize + strlen(szFileName) + 1;
115         }
116
117         size++;
118
119         /* Fill the structure */
120         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
121         if(!hGlobal) return hGlobal;
122
123         pDropFiles = (DROPFILES *)GlobalLock(hGlobal);
124         pDropFiles->pFiles = sizeof(DROPFILES);
125         pDropFiles->fWide = FALSE;
126
127         offset = pDropFiles->pFiles;
128         strcpy(szFileName, szRootPath);
129         
130         for (i=0; i<cidl;i++)
131         {
132           
133           _ILSimpleGetText(apidl[i], szFileName + rootsize, MAX_PATH - rootsize);
134           size = strlen(szFileName) + 1;
135           strcpy(((char*)pDropFiles)+offset, szFileName);
136           offset += size;
137         }
138
139         ((char*)pDropFiles)[offset] = 0;
140         GlobalUnlock(hGlobal);
141
142         return hGlobal;
143 }
144
145 HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
146 {
147         int i,offset = 0, sizePidl, size;
148         HGLOBAL hGlobal;
149         LPCIDA  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 }