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