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