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