server: Add support for allocating purely client-side user handles.
diff --git a/server/protocol.def b/server/protocol.def
index d7b31f4..a0e1702 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3224,3 +3224,16 @@
unsigned int alpha; /* alpha (0..255) */
unsigned int flags; /* LWA_* flags */
@END
+
+
+/* Allocate an arbitrary user handle */
+@REQ(alloc_user_handle)
+@REPLY
+ user_handle_t handle; /* allocated handle */
+@END
+
+
+/* Free an arbitrary user handle */
+@REQ(free_user_handle)
+ user_handle_t handle; /* handle to free*/
+@END
diff --git a/server/request.h b/server/request.h
index 02c7984..87b6a75 100644
--- a/server/request.h
+++ b/server/request.h
@@ -349,6 +349,8 @@
DECL_HANDLER(add_fd_completion);
DECL_HANDLER(get_window_layered_info);
DECL_HANDLER(set_window_layered_info);
+DECL_HANDLER(alloc_user_handle);
+DECL_HANDLER(free_user_handle);
#ifdef WANT_REQUEST_HANDLERS
@@ -593,6 +595,8 @@
(req_handler)req_add_fd_completion,
(req_handler)req_get_window_layered_info,
(req_handler)req_set_window_layered_info,
+ (req_handler)req_alloc_user_handle,
+ (req_handler)req_free_user_handle,
};
C_ASSERT( sizeof(affinity_t) == 8 );
@@ -1892,6 +1896,10 @@
C_ASSERT( FIELD_OFFSET(struct set_window_layered_info_request, alpha) == 20 );
C_ASSERT( FIELD_OFFSET(struct set_window_layered_info_request, flags) == 24 );
C_ASSERT( sizeof(struct set_window_layered_info_request) == 32 );
+C_ASSERT( FIELD_OFFSET(struct alloc_user_handle_reply, handle) == 8 );
+C_ASSERT( sizeof(struct alloc_user_handle_reply) == 16 );
+C_ASSERT( FIELD_OFFSET(struct free_user_handle_request, handle) == 12 );
+C_ASSERT( sizeof(struct free_user_handle_request) == 16 );
#endif /* WANT_REQUEST_HANDLERS */
diff --git a/server/trace.c b/server/trace.c
index 10c731c..b7dec85 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3780,6 +3780,20 @@
fprintf( stderr, ", flags=%08x", req->flags );
}
+static void dump_alloc_user_handle_request( const struct alloc_user_handle_request *req )
+{
+}
+
+static void dump_alloc_user_handle_reply( const struct alloc_user_handle_reply *req )
+{
+ fprintf( stderr, " handle=%08x", req->handle );
+}
+
+static void dump_free_user_handle_request( const struct free_user_handle_request *req )
+{
+ fprintf( stderr, " handle=%08x", req->handle );
+}
+
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_process_request,
(dump_func)dump_get_new_process_info_request,
@@ -4019,6 +4033,8 @@
(dump_func)dump_add_fd_completion_request,
(dump_func)dump_get_window_layered_info_request,
(dump_func)dump_set_window_layered_info_request,
+ (dump_func)dump_alloc_user_handle_request,
+ (dump_func)dump_free_user_handle_request,
};
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -4260,6 +4276,8 @@
NULL,
(dump_func)dump_get_window_layered_info_reply,
NULL,
+ (dump_func)dump_alloc_user_handle_reply,
+ NULL,
};
static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4501,6 +4519,8 @@
"add_fd_completion",
"get_window_layered_info",
"set_window_layered_info",
+ "alloc_user_handle",
+ "free_user_handle",
};
static const struct
diff --git a/server/user.c b/server/user.c
index 6be1c8f..2515799 100644
--- a/server/user.c
+++ b/server/user.c
@@ -20,6 +20,7 @@
#include "thread.h"
#include "user.h"
+#include "request.h"
struct user_handle
{
@@ -164,3 +165,21 @@
}
return NULL;
}
+
+/* allocate an arbitrary user handle */
+DECL_HANDLER(alloc_user_handle)
+{
+ reply->handle = alloc_user_handle( NULL, USER_CLIENT );
+}
+
+
+/* free an arbitrary user handle */
+DECL_HANDLER(free_user_handle)
+{
+ struct user_handle *entry;
+
+ if ((entry = handle_to_entry( req->handle )) && entry->type == USER_CLIENT)
+ free_user_entry( entry );
+ else
+ set_error( STATUS_INVALID_HANDLE );
+}
diff --git a/server/user.h b/server/user.h
index 166d20b..bf1e23c 100644
--- a/server/user.h
+++ b/server/user.h
@@ -35,7 +35,8 @@
enum user_object
{
USER_WINDOW = 1,
- USER_HOOK
+ USER_HOOK,
+ USER_CLIENT /* arbitrary client handle */
};
#define DESKTOP_ATOM ((atom_t)32769)