Add 16<->32 bit message mappings for WM_COPYDATA messages.
[wine] / dlls / user / property.c
1 /*
2  * Window properties
3  *
4  * Copyright 1995, 1996, 2001 Alexandre Julliard
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
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <stdarg.h>
25 #include <string.h>
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "wownt32.h"
31 #include "wine/winuser16.h"
32 #include "wine/server.h"
33
34 /* size of buffer needed to store an atom string */
35 #define ATOM_BUFFER_SIZE 256
36
37
38 /***********************************************************************
39  *              get_properties
40  *
41  * Retrieve the list of properties of a given window.
42  * Returned buffer must be freed by caller.
43  */
44 static property_data_t *get_properties( HWND hwnd, int *count )
45 {
46     property_data_t *data;
47     int total = 32;
48
49     while (total)
50     {
51         int res = 0;
52         if (!(data = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*data) ))) break;
53         *count = 0;
54         SERVER_START_REQ( get_window_properties )
55         {
56             req->window = hwnd;
57             wine_server_add_data( req, data, total * sizeof(*data) );
58             if (!wine_server_call( req )) res = reply->total;
59         }
60         SERVER_END_REQ;
61         if (res && res <= total)
62         {
63             *count = res;
64             return data;
65         }
66         HeapFree( GetProcessHeap(), 0, data );
67         total = res;  /* restart with larger buffer */
68     }
69     return NULL;
70 }
71
72
73 /***********************************************************************
74  *              EnumPropsA_relay
75  *
76  * relay to call the EnumProps callback function from EnumPropsEx
77  */
78 static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
79 {
80     PROPENUMPROCA func = (PROPENUMPROCA)lparam;
81     return func( hwnd, str, handle );
82 }
83
84
85 /***********************************************************************
86  *              EnumPropsW_relay
87  *
88  * relay to call the EnumProps callback function from EnumPropsEx
89  */
90 static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
91 {
92     PROPENUMPROCW func = (PROPENUMPROCW)lparam;
93     return func( hwnd, str, handle );
94 }
95
96
97 /***********************************************************************
98  *              EnumPropsA   (USER32.@)
99  */
100 INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
101 {
102     return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
103 }
104
105
106 /***********************************************************************
107  *              EnumPropsW   (USER32.@)
108  */
109 INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
110 {
111     return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
112 }
113
114
115 /***********************************************************************
116  *              GetPropA   (USER32.@)
117  */
118 HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
119 {
120     ATOM atom;
121     HANDLE ret = 0;
122
123     if (!HIWORD(str)) atom = LOWORD(str);
124     else if (!(atom = GlobalFindAtomA( str ))) return 0;
125
126     SERVER_START_REQ( get_window_property )
127     {
128         req->window = hwnd;
129         req->atom = atom;
130         if (!wine_server_call_err( req )) ret = reply->handle;
131     }
132     SERVER_END_REQ;
133     return ret;
134 }
135
136
137 /***********************************************************************
138  *              GetPropW   (USER32.@)
139  */
140 HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
141 {
142     ATOM atom;
143     HANDLE ret = 0;
144
145     if (!HIWORD(str)) atom = LOWORD(str);
146     else if (!(atom = GlobalFindAtomW( str ))) return 0;
147
148     SERVER_START_REQ( get_window_property )
149     {
150         req->window = hwnd;
151         req->atom = atom;
152         if (!wine_server_call_err( req )) ret = reply->handle;
153     }
154     SERVER_END_REQ;
155     return ret;
156 }
157
158
159 /***********************************************************************
160  *              SetPropA   (USER32.@)
161  */
162 BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
163 {
164     ATOM atom;
165     BOOL ret;
166
167     if (!HIWORD(str)) atom = LOWORD(str);
168     else if (!(atom = GlobalAddAtomA( str ))) return FALSE;
169
170     SERVER_START_REQ( set_window_property )
171     {
172         req->window = hwnd;
173         req->atom   = atom;
174         req->string = (HIWORD(str) != 0);
175         req->handle = handle;
176         ret = !wine_server_call_err( req );
177     }
178     SERVER_END_REQ;
179
180     if (HIWORD(str)) GlobalDeleteAtom( atom );
181     return ret;
182 }
183
184
185 /***********************************************************************
186  *              SetPropW   (USER32.@)
187  */
188 BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
189 {
190     ATOM atom;
191     BOOL ret;
192
193     if (!HIWORD(str)) atom = LOWORD(str);
194     else if (!(atom = GlobalAddAtomW( str ))) return FALSE;
195
196     SERVER_START_REQ( set_window_property )
197     {
198         req->window = hwnd;
199         req->atom   = atom;
200         req->string = (HIWORD(str) != 0);
201         req->handle = handle;
202         ret = !wine_server_call_err( req );
203     }
204     SERVER_END_REQ;
205
206     if (HIWORD(str)) GlobalDeleteAtom( atom );
207     return ret;
208 }
209
210
211 /***********************************************************************
212  *              RemovePropA   (USER32.@)
213  */
214 HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
215 {
216     ATOM atom;
217     HANDLE ret = 0;
218
219     if (!HIWORD(str)) return RemovePropW( hwnd, MAKEINTATOMW(LOWORD(str)) );
220
221     if ((atom = GlobalAddAtomA( str )))
222     {
223         ret = RemovePropW( hwnd, MAKEINTATOMW(atom) );
224         GlobalDeleteAtom( atom );
225     }
226     return ret;
227 }
228
229
230 /***********************************************************************
231  *              RemovePropW   (USER32.@)
232  */
233 HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
234 {
235     ATOM atom;
236     HANDLE ret = 0;
237
238     if (!HIWORD(str)) atom = LOWORD(str);
239     else if (!(atom = GlobalAddAtomW( str ))) return 0;
240
241     SERVER_START_REQ( remove_window_property )
242     {
243         req->window = hwnd;
244         req->atom   = atom;
245         if (!wine_server_call_err( req )) ret = reply->handle;
246     }
247     SERVER_END_REQ;
248
249     if (HIWORD(str)) GlobalDeleteAtom( atom );
250     return ret;
251 }
252
253
254 /***********************************************************************
255  *              EnumPropsExA   (USER32.@)
256  */
257 INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
258 {
259     int ret = -1, i, count;
260     property_data_t *list = get_properties( hwnd, &count );
261
262     if (list)
263     {
264         for (i = 0; i < count; i++)
265         {
266             char string[ATOM_BUFFER_SIZE];
267             if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
268             if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break;
269         }
270         HeapFree( GetProcessHeap(), 0, list );
271     }
272     return ret;
273 }
274
275
276 /***********************************************************************
277  *              EnumPropsExW   (USER32.@)
278  */
279 INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
280 {
281     int ret = -1, i, count;
282     property_data_t *list = get_properties( hwnd, &count );
283
284     if (list)
285     {
286         for (i = 0; i < count; i++)
287         {
288             WCHAR string[ATOM_BUFFER_SIZE];
289             if (!GlobalGetAtomNameW( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
290             if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break;
291         }
292         HeapFree( GetProcessHeap(), 0, list );
293     }
294     return ret;
295 }
296
297
298 /***********************************************************************
299  *              EnumProps   (USER.27)
300  */
301 INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
302 {
303     int ret = -1, i, count;
304     property_data_t *list = get_properties( HWND_32(hwnd), &count );
305
306     if (list)
307     {
308         char string[ATOM_BUFFER_SIZE];
309         SEGPTR segptr = MapLS( string );
310         WORD args[4];
311         DWORD result;
312
313         for (i = 0; i < count; i++)
314         {
315             if (list[i].string)  /* it was a string originally */
316             {
317                 if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
318                 args[3] = hwnd;
319                 args[2] = SELECTOROF(segptr);
320                 args[1] = OFFSETOF(segptr);
321                 args[0] = LOWORD(list[i].handle);
322             }
323             else
324             {
325                 args[3] = hwnd;
326                 args[2] = 0;
327                 args[1] = list[i].atom;
328                 args[0] = LOWORD(list[i].handle);
329             }
330             WOWCallback16Ex( (DWORD)func, WCB16_PASCAL, sizeof(args), args, &result );
331             if (!(ret = LOWORD(result))) break;
332         }
333         UnMapLS( segptr );
334         HeapFree( GetProcessHeap(), 0, list );
335     }
336     return ret;
337 }