Store window properties in the server. Moved property.c to dlls/user.
diff --git a/dlls/user/Makefile.in b/dlls/user/Makefile.in
index b92b019..d3c4984 100644
--- a/dlls/user/Makefile.in
+++ b/dlls/user/Makefile.in
@@ -23,6 +23,7 @@
mouse.c \
msg16.c \
network.c \
+ property.c \
resource.c \
text.c \
thunk.c \
diff --git a/dlls/user/property.c b/dlls/user/property.c
new file mode 100644
index 0000000..a3d32ec
--- /dev/null
+++ b/dlls/user/property.c
@@ -0,0 +1,299 @@
+/*
+ * Window properties
+ *
+ * Copyright 1995, 1996, 2001 Alexandre Julliard
+ */
+
+#include <string.h>
+
+#include "windef.h"
+#include "wingdi.h"
+#include "wine/winuser16.h"
+#include "wine/server.h"
+#include "heap.h"
+
+/* size of buffer needed to store an atom string */
+#define ATOM_BUFFER_SIZE 256
+
+
+/***********************************************************************
+ * get_properties
+ *
+ * Retrieve the list of properties of a given window.
+ * Returned buffer must be freed by caller.
+ */
+static property_data_t *get_properties( HWND hwnd, int *count )
+{
+ property_data_t *ret = NULL;
+
+ SERVER_START_VAR_REQ( get_window_properties, REQUEST_MAX_VAR_SIZE )
+ {
+ req->window = hwnd;
+ if (!SERVER_CALL())
+ {
+ size_t size = server_data_size(req);
+ if (size)
+ {
+ property_data_t *data = server_data_ptr(req);
+ if ((ret = HeapAlloc( GetProcessHeap(), 0, size ))) memcpy( ret, data, size );
+ *count = size / sizeof(*data);
+ }
+ }
+ }
+ SERVER_END_VAR_REQ;
+ return ret;
+}
+
+
+/***********************************************************************
+ * EnumPropsA_relay
+ *
+ * relay to call the EnumProps callback function from EnumPropsEx
+ */
+static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
+{
+ PROPENUMPROCA func = (PROPENUMPROCA)lparam;
+ return func( hwnd, str, handle );
+}
+
+
+/***********************************************************************
+ * EnumPropsW_relay
+ *
+ * relay to call the EnumProps callback function from EnumPropsEx
+ */
+static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
+{
+ PROPENUMPROCW func = (PROPENUMPROCW)lparam;
+ return func( hwnd, str, handle );
+}
+
+
+/***********************************************************************
+ * EnumPropsA (USER32.@)
+ */
+INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
+{
+ return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
+}
+
+
+/***********************************************************************
+ * EnumPropsW (USER32.@)
+ */
+INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
+{
+ return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
+}
+
+
+/***********************************************************************
+ * GetPropA (USER32.@)
+ */
+HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
+{
+ ATOM atom;
+ HANDLE ret = 0;
+
+ if (!HIWORD(str)) atom = LOWORD(str);
+ else if (!(atom = GlobalFindAtomA( str ))) return 0;
+
+ SERVER_START_REQ( get_window_property )
+ {
+ req->window = hwnd;
+ req->atom = atom;
+ if (!SERVER_CALL_ERR()) ret = req->handle;
+ }
+ SERVER_END_REQ;
+ return ret;
+}
+
+
+/***********************************************************************
+ * GetPropW (USER32.@)
+ */
+HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
+{
+ ATOM atom;
+ HANDLE ret = 0;
+
+ if (!HIWORD(str)) atom = LOWORD(str);
+ else if (!(atom = GlobalFindAtomW( str ))) return 0;
+
+ SERVER_START_REQ( get_window_property )
+ {
+ req->window = hwnd;
+ req->atom = atom;
+ if (!SERVER_CALL_ERR()) ret = req->handle;
+ }
+ SERVER_END_REQ;
+ return ret;
+}
+
+
+/***********************************************************************
+ * SetPropA (USER32.@)
+ */
+BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
+{
+ ATOM atom;
+ BOOL ret;
+
+ if (!HIWORD(str)) atom = LOWORD(str);
+ else if (!(atom = GlobalAddAtomA( str ))) return FALSE;
+
+ SERVER_START_REQ( set_window_property )
+ {
+ req->window = hwnd;
+ req->atom = atom;
+ req->string = (HIWORD(str) != 0);
+ req->handle = handle;
+ ret = !SERVER_CALL_ERR();
+ }
+ SERVER_END_REQ;
+
+ if (HIWORD(str)) GlobalDeleteAtom( atom );
+ return ret;
+}
+
+
+/***********************************************************************
+ * SetPropW (USER32.@)
+ */
+BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
+{
+ ATOM atom;
+ BOOL ret;
+
+ if (!HIWORD(str)) atom = LOWORD(str);
+ else if (!(atom = GlobalAddAtomW( str ))) return FALSE;
+
+ SERVER_START_REQ( set_window_property )
+ {
+ req->window = hwnd;
+ req->atom = atom;
+ req->string = (HIWORD(str) != 0);
+ req->handle = handle;
+ ret = !SERVER_CALL_ERR();
+ }
+ SERVER_END_REQ;
+
+ if (HIWORD(str)) GlobalDeleteAtom( atom );
+ return ret;
+}
+
+
+/***********************************************************************
+ * RemovePropA (USER32.@)
+ */
+HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
+{
+ ATOM atom;
+ HANDLE ret = 0;
+
+ if (!HIWORD(str)) return RemovePropW( hwnd, MAKEINTATOMW(LOWORD(str)) );
+
+ if ((atom = GlobalAddAtomA( str )))
+ {
+ ret = RemovePropW( hwnd, MAKEINTATOMW(atom) );
+ GlobalDeleteAtom( atom );
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * RemovePropW (USER32.@)
+ */
+HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
+{
+ ATOM atom;
+ HANDLE ret = 0;
+
+ if (!HIWORD(str)) atom = LOWORD(str);
+ else if (!(atom = GlobalAddAtomW( str ))) return 0;
+
+ SERVER_START_REQ( remove_window_property )
+ {
+ req->window = hwnd;
+ req->atom = atom;
+ if (!SERVER_CALL_ERR()) ret = req->handle;
+ }
+ SERVER_END_REQ;
+
+ if (HIWORD(str)) GlobalDeleteAtom( atom );
+ return ret;
+}
+
+
+/***********************************************************************
+ * EnumPropsExA (USER32.@)
+ */
+INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
+{
+ int ret = -1, i, count;
+ property_data_t *list = get_properties( hwnd, &count );
+
+ if (list)
+ {
+ for (i = 0; i < count; i++)
+ {
+ char string[ATOM_BUFFER_SIZE];
+ if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
+ if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break;
+ }
+ HeapFree( GetProcessHeap(), 0, list );
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * EnumPropsExW (USER32.@)
+ */
+INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
+{
+ int ret = -1, i, count;
+ property_data_t *list = get_properties( hwnd, &count );
+
+ if (list)
+ {
+ for (i = 0; i < count; i++)
+ {
+ WCHAR string[ATOM_BUFFER_SIZE];
+ if (!GlobalGetAtomNameW( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
+ if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break;
+ }
+ HeapFree( GetProcessHeap(), 0, list );
+ }
+ return ret;
+}
+
+
+/***********************************************************************
+ * EnumProps (USER.27)
+ */
+INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
+{
+ int ret = -1, i, count;
+ property_data_t *list = get_properties( hwnd, &count );
+
+ if (list)
+ {
+ char *string = SEGPTR_ALLOC( ATOM_BUFFER_SIZE );
+ for (i = 0; i < count; i++)
+ {
+ if (list[i].string) /* it was a string originally */
+ {
+ if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
+ ret = func( hwnd, SEGPTR_GET(string), list[i].handle );
+ }
+ else
+ ret = func( hwnd, list[i].atom, list[i].handle );
+ if (!ret) break;
+ }
+ SEGPTR_FREE( string );
+ HeapFree( GetProcessHeap(), 0, list );
+ }
+ return ret;
+}
diff --git a/include/win.h b/include/win.h
index 5178844..f454d11 100644
--- a/include/win.h
+++ b/include/win.h
@@ -35,7 +35,6 @@
LPWSTR text; /* Window text */
void *pVScroll; /* Vertical scroll-bar info */
void *pHScroll; /* Horizontal scroll-bar info */
- void *pProp; /* Pointer to properties list */
struct tagDCE *dce; /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
HGLOBAL16 hmemTaskQ; /* Task queue global memory handle */
HRGN hrgnUpdate; /* Update region */
@@ -122,8 +121,6 @@
extern BOOL16 DRAG_QueryUpdate( HWND, SEGPTR, BOOL );
extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ); /* windows/defwnd.c */
-extern void PROPERTY_RemoveWindowProps( HWND hwnd ); /* windows/property.c */
-
/* Classes functions */
struct tagCLASS; /* opaque structure */
struct builtin_class_descr;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index d798532..5eeec43 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -132,6 +132,14 @@
};
+typedef struct
+{
+ atom_t atom;
+ short string;
+ handle_t handle;
+} property_data_t;
+
+
@@ -1644,6 +1652,46 @@
};
+
+struct set_window_property_request
+{
+ struct request_header __header;
+ user_handle_t window;
+ atom_t atom;
+ int string;
+ handle_t handle;
+};
+
+
+
+struct remove_window_property_request
+{
+ struct request_header __header;
+ user_handle_t window;
+ atom_t atom;
+ handle_t handle;
+};
+
+
+
+struct get_window_property_request
+{
+ struct request_header __header;
+ user_handle_t window;
+ atom_t atom;
+ handle_t handle;
+};
+
+
+
+struct get_window_properties_request
+{
+ struct request_header __header;
+ user_handle_t window;
+ /* VARARG(props,properties); */
+};
+
+
enum request
{
REQ_new_process,
@@ -1775,6 +1823,10 @@
REQ_get_window_parents,
REQ_get_window_children,
REQ_get_window_tree,
+ REQ_set_window_property,
+ REQ_remove_window_property,
+ REQ_get_window_property,
+ REQ_get_window_properties,
REQ_NB_REQUESTS
};
@@ -1911,8 +1963,12 @@
struct get_window_parents_request get_window_parents;
struct get_window_children_request get_window_children;
struct get_window_tree_request get_window_tree;
+ struct set_window_property_request set_window_property;
+ struct remove_window_property_request remove_window_property;
+ struct get_window_property_request get_window_property;
+ struct get_window_properties_request get_window_properties;
};
-#define SERVER_PROTOCOL_VERSION 58
+#define SERVER_PROTOCOL_VERSION 59
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index fa0b81e..95bc13a 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -133,6 +133,14 @@
int signaled; /* wait result */
};
+/* structure returned in the list of window properties */
+typedef struct
+{
+ atom_t atom; /* property atom */
+ short string; /* was atom a string originally? */
+ handle_t handle; /* handle stored in property */
+} property_data_t;
+
/****************************************************************/
/* Request declarations */
@@ -1469,3 +1477,38 @@
user_handle_t first_child; /* first child */
user_handle_t last_child; /* last child */
@END
+
+
+/* Set a window property */
+@REQ(set_window_property)
+ user_handle_t window; /* handle to the window */
+ atom_t atom; /* property atom (high-word set if it was a string) */
+ int string; /* was atom a string originally? */
+ handle_t handle; /* handle to store */
+@END
+
+
+/* Remove a window property */
+@REQ(remove_window_property)
+ user_handle_t window; /* handle to the window */
+ atom_t atom; /* property atom */
+@REPLY
+ handle_t handle; /* handle stored in property */
+@END
+
+
+/* Get a window property */
+@REQ(get_window_property)
+ user_handle_t window; /* handle to the window */
+ atom_t atom; /* property atom */
+@REPLY
+ handle_t handle; /* handle stored in property */
+@END
+
+
+/* Get the list of properties of a window */
+@REQ(get_window_properties)
+ user_handle_t window; /* handle to the window */
+@REPLY
+ VARARG(props,properties); /* list of properties */
+@END
diff --git a/server/request.h b/server/request.h
index 1269e17..8939854 100644
--- a/server/request.h
+++ b/server/request.h
@@ -194,6 +194,10 @@
DECL_HANDLER(get_window_parents);
DECL_HANDLER(get_window_children);
DECL_HANDLER(get_window_tree);
+DECL_HANDLER(set_window_property);
+DECL_HANDLER(remove_window_property);
+DECL_HANDLER(get_window_property);
+DECL_HANDLER(get_window_properties);
#ifdef WANT_REQUEST_HANDLERS
@@ -329,6 +333,10 @@
(req_handler)req_get_window_parents,
(req_handler)req_get_window_children,
(req_handler)req_get_window_tree,
+ (req_handler)req_set_window_property,
+ (req_handler)req_remove_window_property,
+ (req_handler)req_get_window_property,
+ (req_handler)req_get_window_properties,
};
#endif /* WANT_REQUEST_HANDLERS */
diff --git a/server/trace.c b/server/trace.c
index 094ff25..bd4de67 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -271,6 +271,23 @@
return get_size(req);
}
+static size_t dump_varargs_properties( const void *req )
+{
+ const property_data_t *prop = get_data(req);
+ size_t len = get_size(req) / sizeof(*prop);
+
+ fputc( '{', stderr );
+ while (len > 0)
+ {
+ fprintf( stderr, "{atom=%04x,str=%d,handle=%08x}",
+ prop->atom, prop->string, prop->handle );
+ prop++;
+ if (--len) fputc( ',', stderr );
+ }
+ fputc( '}', stderr );
+ return get_size(req);
+}
+
typedef void (*dump_func)( const void *req );
/* Everything below this line is generated automatically by tools/make_requests */
@@ -1743,6 +1760,47 @@
fprintf( stderr, " last_child=%08x", req->last_child );
}
+static void dump_set_window_property_request( const struct set_window_property_request *req )
+{
+ fprintf( stderr, " window=%08x,", req->window );
+ fprintf( stderr, " atom=%04x,", req->atom );
+ fprintf( stderr, " string=%d,", req->string );
+ fprintf( stderr, " handle=%d", req->handle );
+}
+
+static void dump_remove_window_property_request( const struct remove_window_property_request *req )
+{
+ fprintf( stderr, " window=%08x,", req->window );
+ fprintf( stderr, " atom=%04x", req->atom );
+}
+
+static void dump_remove_window_property_reply( const struct remove_window_property_request *req )
+{
+ fprintf( stderr, " handle=%d", req->handle );
+}
+
+static void dump_get_window_property_request( const struct get_window_property_request *req )
+{
+ fprintf( stderr, " window=%08x,", req->window );
+ fprintf( stderr, " atom=%04x", req->atom );
+}
+
+static void dump_get_window_property_reply( const struct get_window_property_request *req )
+{
+ fprintf( stderr, " handle=%d", req->handle );
+}
+
+static void dump_get_window_properties_request( const struct get_window_properties_request *req )
+{
+ fprintf( stderr, " window=%08x", req->window );
+}
+
+static void dump_get_window_properties_reply( const struct get_window_properties_request *req )
+{
+ fprintf( stderr, " props=" );
+ cur_pos += dump_varargs_properties( req );
+}
+
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
@@ -1873,6 +1931,10 @@
(dump_func)dump_get_window_parents_request,
(dump_func)dump_get_window_children_request,
(dump_func)dump_get_window_tree_request,
+ (dump_func)dump_set_window_property_request,
+ (dump_func)dump_remove_window_property_request,
+ (dump_func)dump_get_window_property_request,
+ (dump_func)dump_get_window_properties_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -2005,6 +2067,10 @@
(dump_func)dump_get_window_parents_reply,
(dump_func)dump_get_window_children_reply,
(dump_func)dump_get_window_tree_reply,
+ (dump_func)0,
+ (dump_func)dump_remove_window_property_reply,
+ (dump_func)dump_get_window_property_reply,
+ (dump_func)dump_get_window_properties_reply,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -2137,6 +2203,10 @@
"get_window_parents",
"get_window_children",
"get_window_tree",
+ "set_window_property",
+ "remove_window_property",
+ "get_window_property",
+ "get_window_properties",
};
/* ### make_requests end ### */
diff --git a/server/window.c b/server/window.c
index c57aadf..ff9ba82 100644
--- a/server/window.c
+++ b/server/window.c
@@ -12,6 +12,22 @@
#include "process.h"
#include "user.h"
+/* a window property */
+struct property
+{
+ unsigned short type; /* property type (see below) */
+ atom_t atom; /* property atom */
+ handle_t handle; /* property handle (user-defined storage) */
+};
+
+enum property_type
+{
+ PROP_TYPE_FREE, /* free entry */
+ PROP_TYPE_STRING, /* atom that was originally a string */
+ PROP_TYPE_ATOM /* plain atom */
+};
+
+
struct window
{
struct window *parent; /* parent window */
@@ -23,7 +39,10 @@
struct window *prev; /* prev window in Z-order */
user_handle_t handle; /* full handle for this window */
struct thread *thread; /* thread owning the window */
- unsigned int atom; /* class atom */
+ atom_t atom; /* class atom */
+ int prop_inuse; /* number of in-use window properties */
+ int prop_alloc; /* number of allocated window properties */
+ struct property *properties; /* window properties array */
};
static struct window *top_window; /* top-level (desktop) window */
@@ -83,6 +102,118 @@
}
}
+/* set a window property */
+static void set_property( struct window *win, atom_t atom, handle_t handle,
+ enum property_type type )
+{
+ int i, free = -1;
+ struct property *new_props;
+
+ /* check if it exists already */
+ for (i = 0; i < win->prop_inuse; i++)
+ {
+ if (win->properties[i].type == PROP_TYPE_FREE)
+ {
+ free = i;
+ continue;
+ }
+ if (win->properties[i].atom == atom)
+ {
+ win->properties[i].type = type;
+ win->properties[i].handle = handle;
+ return;
+ }
+ }
+
+ /* need to add an entry */
+ if (!grab_global_atom( atom )) return;
+ if (free == -1)
+ {
+ /* no free entry */
+ if (win->prop_inuse >= win->prop_alloc)
+ {
+ /* need to grow the array */
+ if (!(new_props = realloc( win->properties,
+ sizeof(*new_props) * (win->prop_alloc + 16) )))
+ {
+ set_error( STATUS_NO_MEMORY );
+ release_global_atom( atom );
+ return;
+ }
+ win->prop_alloc += 16;
+ win->properties = new_props;
+ }
+ free = win->prop_inuse++;
+ }
+ win->properties[free].atom = atom;
+ win->properties[free].type = type;
+ win->properties[free].handle = handle;
+}
+
+/* remove a window property */
+static handle_t remove_property( struct window *win, atom_t atom )
+{
+ int i;
+
+ for (i = 0; i < win->prop_inuse; i++)
+ {
+ if (win->properties[i].type == PROP_TYPE_FREE) continue;
+ if (win->properties[i].atom == atom)
+ {
+ release_global_atom( atom );
+ win->properties[i].type = PROP_TYPE_FREE;
+ return win->properties[i].handle;
+ }
+ }
+ /* FIXME: last error? */
+ return 0;
+}
+
+/* find a window property */
+static handle_t get_property( struct window *win, atom_t atom )
+{
+ int i;
+
+ for (i = 0; i < win->prop_inuse; i++)
+ {
+ if (win->properties[i].type == PROP_TYPE_FREE) continue;
+ if (win->properties[i].atom == atom) return win->properties[i].handle;
+ }
+ /* FIXME: last error? */
+ return 0;
+}
+
+/* destroy all properties of a window */
+inline static void destroy_properties( struct window *win )
+{
+ int i;
+
+ if (!win->properties) return;
+ for (i = 0; i < win->prop_inuse; i++)
+ {
+ if (win->properties[i].type == PROP_TYPE_FREE) continue;
+ release_global_atom( win->properties[i].atom );
+ }
+ free( win->properties );
+}
+
+/* enum all properties into the data array */
+static int enum_properties( struct window *win, property_data_t *data, int max )
+{
+ int i, count;
+
+ for (i = count = 0; i < win->prop_inuse && count < max; i++)
+ {
+ if (win->properties[i].type == PROP_TYPE_FREE) continue;
+ data->atom = win->properties[i].atom;
+ data->string = (win->properties[i].type == PROP_TYPE_STRING);
+ data->handle = win->properties[i].handle;
+ data++;
+ count++;
+ }
+ return count;
+}
+
/* destroy a window */
static void destroy_window( struct window *win )
{
@@ -104,14 +235,14 @@
if (win->thread->queue) queue_cleanup_window( win->thread, win->handle );
free_user_handle( win->handle );
+ destroy_properties( win );
unlink_window( win );
memset( win, 0x55, sizeof(*win) );
free( win );
}
/* create a new window structure (note: the window is not linked in the window tree) */
-static struct window *create_window( struct window *parent, struct window *owner,
- unsigned int atom )
+static struct window *create_window( struct window *parent, struct window *owner, atom_t atom )
{
struct window *win = mem_alloc( sizeof(*win) );
if (!win) return NULL;
@@ -128,6 +259,9 @@
win->first_unlinked = NULL;
win->thread = current;
win->atom = atom;
+ win->prop_inuse = 0;
+ win->prop_alloc = 0;
+ win->properties = NULL;
if (parent) /* put it on parent unlinked list */
{
@@ -340,3 +474,43 @@
req->first_child = win->first_child ? win->first_child->handle : 0;
req->last_child = win->last_child ? win->last_child->handle : 0;
}
+
+
+/* set a window property */
+DECL_HANDLER(set_window_property)
+{
+ struct window *win = get_window( req->window );
+
+ if (win) set_property( win, req->atom, req->handle,
+ req->string ? PROP_TYPE_STRING : PROP_TYPE_ATOM );
+}
+
+
+/* remove a window property */
+DECL_HANDLER(remove_window_property)
+{
+ struct window *win = get_window( req->window );
+ req->handle = 0;
+ if (win) req->handle = remove_property( win, req->atom );
+}
+
+
+/* get a window property */
+DECL_HANDLER(get_window_property)
+{
+ struct window *win = get_window( req->window );
+ req->handle = 0;
+ if (win) req->handle = get_property( win, req->atom );
+}
+
+
+/* get the list of properties of a window */
+DECL_HANDLER(get_window_properties)
+{
+ int count = 0;
+ property_data_t *data = get_req_data(req);
+ struct window *win = get_window( req->window );
+
+ if (win) count = enum_properties( win, data, get_req_data_size(req) / sizeof(*data) );
+ set_req_data_size( req, count * sizeof(*data) );
+}
diff --git a/windows/Makefile.in b/windows/Makefile.in
index a971ec6..f9ba851 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -26,7 +26,6 @@
multimon.c \
nonclient.c \
painting.c \
- property.c \
queue.c \
rect.c \
scroll.c \
diff --git a/windows/property.c b/windows/property.c
deleted file mode 100644
index 4c5fce6..0000000
--- a/windows/property.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Window properties
- *
- * Copyright 1995, 1996 Alexandre Julliard
- */
-
-#include <string.h>
-
-#include "windef.h"
-#include "wingdi.h"
-#include "wine/winuser16.h"
-#include "win.h"
-#include "heap.h"
-#include "debugtools.h"
-
-DEFAULT_DEBUG_CHANNEL(prop);
-
-
-typedef struct tagPROPERTY
-{
- struct tagPROPERTY *next; /* Next property in window list */
- HANDLE handle; /* User's data */
- LPSTR string; /* Property string (or atom) */
-} PROPERTY;
-
-
-#define MAX_ATOM_LEN 255
-
-/***********************************************************************
- * PROP_FindProp
- */
-static PROPERTY *PROP_FindProp( HWND hwnd, LPCSTR str )
-{
- ATOM atom;
- PROPERTY *prop;
- WND *pWnd = WIN_FindWndPtr( hwnd );
-
- if (!pWnd) return NULL;
- if (HIWORD(str))
- {
- atom = GlobalFindAtomA( str );
- for (prop = pWnd->pProp; prop; prop = prop->next)
- {
- if (HIWORD(prop->string))
- {
- if (!lstrcmpiA( prop->string, str )) goto END;
- }
- else if (LOWORD(prop->string) == atom) goto END;
- }
- }
- else /* atom */
- {
- atom = LOWORD(str);
- for (prop = pWnd->pProp; (prop); prop = prop->next)
- {
- if (HIWORD(prop->string))
- {
- if (GlobalFindAtomA( prop->string ) == atom) goto END;
- }
- else if (LOWORD(prop->string) == atom) goto END;
- }
- }
- prop = NULL;
-END:
- WIN_ReleaseWndPtr(pWnd);
- return prop;
-}
-
-
-/***********************************************************************
- * GetPropA (USER32.@)
- */
-HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
-{
- PROPERTY *prop = PROP_FindProp( hwnd, str );
-
- if (HIWORD(str))
- TRACE("(%08x,'%s'): returning %08x\n",
- hwnd, str, prop ? prop->handle : 0 );
- else
- TRACE("(%08x,#%04x): returning %08x\n",
- hwnd, LOWORD(str), prop ? prop->handle : 0 );
-
- return prop ? prop->handle : 0;
-}
-
-
-/***********************************************************************
- * GetPropW (USER32.@)
- */
-HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
-{
- LPSTR strA;
- HANDLE ret;
-
- if (!HIWORD(str)) return GetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
- strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
- ret = GetPropA( hwnd, strA );
- HeapFree( GetProcessHeap(), 0, strA );
- return ret;
-}
-
-
-/***********************************************************************
- * SetPropA (USER32.@)
- */
-BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
-{
- PROPERTY *prop;
-
- if (HIWORD(str))
- TRACE("%04x '%s' %08x\n", hwnd, str, handle );
- else
- TRACE("%04x #%04x %08x\n",
- hwnd, LOWORD(str), handle );
-
- if (!(prop = PROP_FindProp( hwnd, str )))
- {
- /* We need to create it */
- WND *pWnd = WIN_FindWndPtr( hwnd );
- if (!pWnd) return FALSE;
- if (!(prop = HeapAlloc( GetProcessHeap(), 0, sizeof(*prop) )))
- {
- WIN_ReleaseWndPtr(pWnd);
- return FALSE;
- }
- if (!(prop->string = SEGPTR_STRDUP(str)))
- {
- HeapFree( GetProcessHeap(), 0, prop );
- WIN_ReleaseWndPtr(pWnd);
- return FALSE;
-
- }
- prop->next = pWnd->pProp;
- pWnd->pProp = prop;
- WIN_ReleaseWndPtr(pWnd);
- }
- prop->handle = handle;
- return TRUE;
-}
-
-
-/***********************************************************************
- * SetPropW (USER32.@)
- */
-BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
-{
- BOOL ret;
- LPSTR strA;
-
- if (!HIWORD(str))
- return SetPropA( hwnd, (LPCSTR)(UINT)LOWORD(str), handle );
- strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
- ret = SetPropA( hwnd, strA, handle );
- HeapFree( GetProcessHeap(), 0, strA );
- return ret;
-}
-
-
-/***********************************************************************
- * RemovePropA (USER32.@)
- */
-HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
-{
- ATOM atom;
- HANDLE handle;
- PROPERTY **pprop, *prop;
- WND *pWnd = WIN_FindWndPtr( hwnd );
-
- if (HIWORD(str))
- TRACE("%04x '%s'\n", hwnd, str );
- else
- TRACE("%04x #%04x\n", hwnd, LOWORD(str));
-
-
- if (!pWnd) return (HANDLE)0;
- if (HIWORD(str))
- {
- atom = GlobalFindAtomA( str );
- for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
- {
- if (HIWORD((*pprop)->string))
- {
- if (!lstrcmpiA( (*pprop)->string, str )) break;
- }
- else if (LOWORD((*pprop)->string) == atom) break;
- }
- }
- else /* atom */
- {
- atom = LOWORD(str);
- for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
- {
- if (HIWORD((*pprop)->string))
- {
- if (GlobalFindAtomA( (*pprop)->string ) == atom) break;
- }
- else if (LOWORD((*pprop)->string) == atom) break;
- }
- }
- WIN_ReleaseWndPtr(pWnd);
- if (!*pprop) return 0;
- prop = *pprop;
- handle = prop->handle;
- *pprop = prop->next;
- SEGPTR_FREE(prop->string);
- HeapFree( GetProcessHeap(), 0, prop );
- return handle;
-}
-
-
-/***********************************************************************
- * RemovePropW (USER32.@)
- */
-HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
-{
- LPSTR strA;
- HANDLE ret;
-
- if (!HIWORD(str))
- return RemovePropA( hwnd, (LPCSTR)(UINT)LOWORD(str) );
- strA = HEAP_strdupWtoA( GetProcessHeap(), 0, str );
- ret = RemovePropA( hwnd, strA );
- HeapFree( GetProcessHeap(), 0, strA );
- return ret;
-}
-
-
-/***********************************************************************
- * PROPERTY_RemoveWindowProps
- *
- * Remove all properties of a window.
- */
-void PROPERTY_RemoveWindowProps( HWND hwnd )
-{
- PROPERTY *prop, *next;
- WND *pWnd = WIN_FindWndPtr( hwnd );
-
- if (!pWnd) return;
- for (prop = pWnd->pProp; (prop); prop = next)
- {
- next = prop->next;
- SEGPTR_FREE( prop->string );
- HeapFree( GetProcessHeap(), 0, prop );
- }
- pWnd->pProp = NULL;
- WIN_ReleaseWndPtr( pWnd );
-}
-
-
-/***********************************************************************
- * EnumProps (USER.27)
- */
-INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
-{
- PROPERTY *prop, *next;
- WND *pWnd;
- INT16 ret = -1;
-
- TRACE("%04x %08x\n", hwnd, (UINT)func );
- if (!(pWnd = WIN_FindWndPtr16( hwnd ))) return -1;
- for (prop = pWnd->pProp; (prop); prop = next)
- {
- /* Already get the next in case the callback */
- /* function removes the current property. */
- next = prop->next;
-
- /* SDK docu seems to suggest that EnumProps16 does not retrieve
- * the string in case of an atom handle, in contrast to Win32 */
-
- TRACE(" Callback: handle=%08x str=%s\n",
- prop->handle, debugstr_a(prop->string) );
- ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
- if (!ret) break;
- }
- WIN_ReleaseWndPtr(pWnd);
- return ret;
-}
-
-
-/* relay to call the EnumProps callback function from EnumPropsEx */
-static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
-{
- PROPENUMPROCA func = (PROPENUMPROCA)lparam;
- return func( hwnd, str, handle );
-}
-
-
-/***********************************************************************
- * EnumPropsA (USER32.@)
- */
-INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
-{
- return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
-}
-
-
-/***********************************************************************
- * EnumPropsExA (USER32.@)
- */
-INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
-{
- PROPERTY *prop, *next;
- WND *pWnd;
- INT ret = -1;
- char atomStr[MAX_ATOM_LEN+1];
- char *pStr;
-
- TRACE("%04x %p %08lx\n", hwnd, func, lParam);
- if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
- for (prop = pWnd->pProp; (prop); prop = next)
- {
- /* Already get the next in case the callback */
- /* function removes the current property. */
- next = prop->next;
-
- if (!HIWORD(prop->string))
- { /* get "real" string the atom points to.
- * This seems to be done for Win32 only */
- if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
- {
- ERR("huh ? Atom %04x not an atom ??\n", LOWORD(prop->string));
- atomStr[0] = '\0';
- }
- pStr = atomStr;
- }
- else
- pStr = prop->string;
-
- TRACE(" Callback: handle=%08x str='%s'\n",
- prop->handle, prop->string );
-
- ret = func( hwnd, pStr, prop->handle, lParam );
- if (!ret) break;
- }
- WIN_ReleaseWndPtr(pWnd);
- return ret;
-}
-
-
-/* relay to call the EnumProps callback function from EnumPropsEx */
-static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
-{
- PROPENUMPROCW func = (PROPENUMPROCW)lparam;
- return func( hwnd, str, handle );
-}
-
-/***********************************************************************
- * EnumPropsW (USER32.@)
- */
-INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
-{
- return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
-}
-
-/***********************************************************************
- * EnumPropsExW (USER32.@)
- */
-INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
-{
- PROPERTY *prop, *next;
- WND *pWnd;
- INT ret = -1;
- char atomStr[MAX_ATOM_LEN+1];
- char *pStr;
- LPWSTR strW;
-
- TRACE("%04x %p %08lx\n", hwnd, func, lParam);
- if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
- for (prop = pWnd->pProp; (prop); prop = next)
- {
- /* Already get the next in case the callback */
- /* function removes the current property. */
- next = prop->next;
-
- if (!HIWORD(prop->string))
- { /* get "real" string the atom points to.
- * This seems to be done for Win32 only */
- if (!(GlobalGetAtomNameA((ATOM)LOWORD(prop->string), atomStr, MAX_ATOM_LEN+1)))
- {
- ERR("huh ? Atom %04x not an atom ??\n",
- (ATOM)LOWORD(prop->string));
- atomStr[0] = '\0';
- }
- pStr = atomStr;
- }
- else
- pStr = prop->string;
-
- TRACE(" Callback: handle=%08x str='%s'\n",
- prop->handle, prop->string );
-
- strW = HEAP_strdupAtoW( GetProcessHeap(), 0, pStr );
-
- ret = func( hwnd, strW, prop->handle, lParam );
- HeapFree( GetProcessHeap(), 0, strW );
- if (!ret) break;
- }
- WIN_ReleaseWndPtr(pWnd);
- return ret;
-}
diff --git a/windows/win.c b/windows/win.c
index 5b37ec7..c35e7c0 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -549,7 +549,6 @@
/* free resources associated with the window */
TIMER_RemoveWindowTimers( hwnd );
- PROPERTY_RemoveWindowProps( hwnd );
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
wndPtr->hmemTaskQ = 0;
@@ -646,7 +645,6 @@
pWndDesktop->dce = NULL;
pWndDesktop->pVScroll = NULL;
pWndDesktop->pHScroll = NULL;
- pWndDesktop->pProp = NULL;
pWndDesktop->wIDmenu = 0;
pWndDesktop->helpContext = 0;
pWndDesktop->flags = 0;
@@ -859,7 +857,6 @@
wndPtr->flags = (type == WIN_PROC_16) ? 0 : WIN_ISWIN32;
wndPtr->pVScroll = NULL;
wndPtr->pHScroll = NULL;
- wndPtr->pProp = NULL;
wndPtr->userdata = 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
? MENU_GetSysMenu( hwnd, 0 ) : 0;