[PATCH 11/11] server: implement and user find_menu_item server call
Thomas Kho
tkho at ucla.edu
Thu Jun 29 15:34:28 CDT 2006
server: implement and user find_menu_item server call
Found this function was a major bottleneck in real-world applications.
Thomas Kho
---
dlls/user/menu.c | 64 +++++++++-------------------------------
include/wine/server_protocol.h | 19 ++++++++++++
server/menu.c | 9 ++++++
server/protocol.def | 11 +++++++
server/request.h | 2 +
server/trace.c | 17 +++++++++++
6 files changed, 72 insertions(+), 50 deletions(-)
diff --git a/dlls/user/menu.c b/dlls/user/menu.c
index 6a2f7d7..717e922 100644
--- a/dlls/user/menu.c
+++ b/dlls/user/menu.c
@@ -855,58 +855,22 @@ static UINT MENU_GetStartOfPrevColumn(
*/
static UINT MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags )
{
- POPUPMENU tmpmenu;
- POPUPMENU *menu = &tmpmenu;
- MENUITEM *fallback = NULL;
- UINT fallback_pos = ITEM_NOT_FOUND;
- UINT i;
-
- if ((*hmenu == (HMENU)0xffff) || (MENU_GetMenu(*hmenu, menu)))
- return ITEM_NOT_FOUND;
- if (wFlags & MF_BYPOSITION)
- {
- if (*nPos >= menu->nItems) return ITEM_NOT_FOUND;
- return *nPos;
- }
- else
+ NTSTATUS ret;
+ UINT retpos = ITEM_NOT_FOUND;
+ SERVER_START_REQ( find_menu_item )
{
- MENUITEM *items;
- MENUITEM *item;
- MENU_GetAllMenuItems(*hmenu, &items);
- item = items;
- for (i = 0; i < menu->nItems; i++, item++)
- {
- if (item->fType & MF_POPUP)
- {
- HMENU hsubmenu = item->hSubMenu;
- UINT subitem = MENU_FindItem( &hsubmenu, nPos, wFlags );
- if (subitem != ITEM_NOT_FOUND)
- {
- *hmenu = hsubmenu;
- MENU_ReleaseMenuItem(items);
- return subitem;
- }
- else if (item->wID == *nPos)
- {
- /* fallback to this item if nothing else found */
- fallback_pos = i;
- fallback = item;
- }
- }
- else if (item->wID == *nPos)
- {
- *nPos = i;
- MENU_ReleaseMenuItem(items);
- return i;
- }
- }
- MENU_ReleaseMenuItem(items);
+ req->handle = *hmenu;
+ req->pos = *nPos;
+ req->flags = wFlags;
+ if ((ret = wine_server_call_err( req )))
+ WARN("error hMenu=0x%x, status=%x\n", (unsigned) *hmenu,
+ (unsigned) ret);
+ *hmenu = reply->handle;
+ *nPos = reply->pos;
+ retpos = reply->retval;
}
-
- if (fallback)
- *nPos = fallback_pos;
-
- return fallback_pos;
+ SERVER_END_REQ;
+ return retpos;
}
/***********************************************************************
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 45c725a..ed578d2 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -3499,6 +3499,22 @@ #define SET_GLOBAL_PROGMAN_WINDOW 0x02
#define SET_GLOBAL_TASKMAN_WINDOW 0x04
+struct find_menu_item_request
+{
+ struct request_header __header;
+ user_handle_t handle;
+ unsigned int pos;
+ unsigned int flags;
+};
+struct find_menu_item_reply
+{
+ struct reply_header __header;
+ user_handle_t handle;
+ unsigned int pos;
+ unsigned int retval;
+};
+
+
struct get_menu_item_info_request
{
struct request_header __header;
@@ -4108,6 +4124,7 @@ enum request
REQ_set_clipboard_info,
REQ_open_token,
REQ_set_global_windows,
+ REQ_find_menu_item,
REQ_get_menu_item_info,
REQ_set_menu_item_info,
REQ_insert_menu_item,
@@ -4336,6 +4353,7 @@ union generic_request
struct set_clipboard_info_request set_clipboard_info_request;
struct open_token_request open_token_request;
struct set_global_windows_request set_global_windows_request;
+ struct find_menu_item_request find_menu_item_request;
struct get_menu_item_info_request get_menu_item_info_request;
struct set_menu_item_info_request set_menu_item_info_request;
struct insert_menu_item_request insert_menu_item_request;
@@ -4562,6 +4580,7 @@ union generic_reply
struct set_clipboard_info_reply set_clipboard_info_reply;
struct open_token_reply open_token_reply;
struct set_global_windows_reply set_global_windows_reply;
+ struct find_menu_item_reply find_menu_item_reply;
struct get_menu_item_info_reply get_menu_item_info_reply;
struct set_menu_item_info_reply set_menu_item_info_reply;
struct insert_menu_item_reply insert_menu_item_reply;
diff --git a/server/menu.c b/server/menu.c
index cc0f781..b640b73 100644
--- a/server/menu.c
+++ b/server/menu.c
@@ -285,6 +285,15 @@ static unsigned int insert_item(user_han
}
+/* find a menu item */
+DECL_HANDLER(find_menu_item)
+{
+ reply->handle = req->handle;
+ reply->pos = req->pos;
+ reply->retval = find_item(&reply->handle, &reply->pos, req->flags);
+}
+
+
/* validate the given menu handle and get menu item info */
DECL_HANDLER(get_menu_item_info)
{
diff --git a/server/protocol.def b/server/protocol.def
index c5653a0..734f190 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2463,6 +2463,17 @@ #define SET_GLOBAL_SHELL_WINDOWS 0x01
#define SET_GLOBAL_PROGMAN_WINDOW 0x02
#define SET_GLOBAL_TASKMAN_WINDOW 0x04
+/* Find menu item */
+ at REQ(find_menu_item)
+ user_handle_t handle;
+ unsigned int pos;
+ unsigned int flags;
+ at REPLY
+ user_handle_t handle;
+ unsigned int pos;
+ unsigned int retval;
+ at END
+
/* Get menu item info */
@REQ(get_menu_item_info)
user_handle_t handle;
diff --git a/server/request.h b/server/request.h
index 9724d5a..317bb0c 100644
--- a/server/request.h
+++ b/server/request.h
@@ -308,6 +308,7 @@ DECL_HANDLER(set_class_info);
DECL_HANDLER(set_clipboard_info);
DECL_HANDLER(open_token);
DECL_HANDLER(set_global_windows);
+DECL_HANDLER(find_menu_item);
DECL_HANDLER(get_menu_item_info);
DECL_HANDLER(set_menu_item_info);
DECL_HANDLER(insert_menu_item);
@@ -535,6 +536,7 @@ static const req_handler req_handlers[RE
(req_handler)req_set_clipboard_info,
(req_handler)req_open_token,
(req_handler)req_set_global_windows,
+ (req_handler)req_find_menu_item,
(req_handler)req_get_menu_item_info,
(req_handler)req_set_menu_item_info,
(req_handler)req_insert_menu_item,
diff --git a/server/trace.c b/server/trace.c
index 7504c08..d32a922 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3049,6 +3049,20 @@ static void dump_set_global_windows_repl
fprintf( stderr, " old_taskman_window=%p", req->old_taskman_window );
}
+static void dump_find_menu_item_request( const struct find_menu_item_request *req )
+{
+ fprintf( stderr, " handle=%p,", req->handle );
+ fprintf( stderr, " pos=%08x,", req->pos );
+ fprintf( stderr, " flags=%08x", req->flags );
+}
+
+static void dump_find_menu_item_reply( const struct find_menu_item_reply *req )
+{
+ fprintf( stderr, " handle=%p,", req->handle );
+ fprintf( stderr, " pos=%08x,", req->pos );
+ fprintf( stderr, " retval=%08x", req->retval );
+}
+
static void dump_get_menu_item_info_request( const struct get_menu_item_info_request *req )
{
fprintf( stderr, " handle=%p,", req->handle );
@@ -3601,6 +3615,7 @@ static const dump_func req_dumpers[REQ_N
(dump_func)dump_set_clipboard_info_request,
(dump_func)dump_open_token_request,
(dump_func)dump_set_global_windows_request,
+ (dump_func)dump_find_menu_item_request,
(dump_func)dump_get_menu_item_info_request,
(dump_func)dump_set_menu_item_info_request,
(dump_func)dump_insert_menu_item_request,
@@ -3825,6 +3840,7 @@ static const dump_func reply_dumpers[REQ
(dump_func)dump_set_clipboard_info_reply,
(dump_func)dump_open_token_reply,
(dump_func)dump_set_global_windows_reply,
+ (dump_func)dump_find_menu_item_reply,
(dump_func)dump_get_menu_item_info_reply,
(dump_func)0,
(dump_func)dump_insert_menu_item_reply,
@@ -4049,6 +4065,7 @@ static const char * const req_names[REQ_
"set_clipboard_info",
"open_token",
"set_global_windows",
+ "find_menu_item",
"get_menu_item_info",
"set_menu_item_info",
"insert_menu_item",
More information about the wine-patches
mailing list