Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
317d113a
Commit
317d113a
authored
Jun 26, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Jul 03, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Add support for invoking serverside event callbacks.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
7223d195
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
97 additions
and
29 deletions
+97
-29
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+6
-6
uia_event.c
dlls/uiautomationcore/uia_event.c
+91
-23
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
317d113a
...
...
@@ -13974,8 +13974,8 @@ static void test_UiaAddEvent_client_proc(void)
SET_EXPECT
(
prov_callback_proxy
);
SET_EXPECT
(
uia_event_callback
);
post_event_message
(
hwnd
,
WM_UIA_TEST_RAISE_EVENT
,
HandleToUlong
(
hwnd
),
PROVIDER_ID
,
ProviderOptions_ServerSideProvider
);
todo_wine
ok
(
!
WaitForSingleObject
(
EventData
.
event_handle
,
2000
),
"Wait for event_handle failed.
\n
"
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
ok
(
!
WaitForSingleObject
(
EventData
.
event_handle
,
2000
),
"Wait for event_handle failed.
\n
"
);
CHECK_CALLED
(
uia_event_callback
);
CHECK_CALLED
(
prov_callback_base_hwnd
);
CHECK_CALLED
(
prov_callback_nonclient
);
todo_wine
CHECK_CALLED
(
prov_callback_proxy
);
...
...
@@ -13995,8 +13995,8 @@ static void test_UiaAddEvent_client_proc(void)
SET_EXPECT
(
uia_event_callback
);
post_event_message
(
hwnd
,
WM_UIA_TEST_RAISE_EVENT
,
0
,
PROVIDER2_ID
,
ProviderOptions_ServerSideProvider
);
todo_wine
ok
(
!
WaitForSingleObject
(
EventData
.
event_handle
,
2000
),
"Wait for event_handle failed.
\n
"
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
ok
(
!
WaitForSingleObject
(
EventData
.
event_handle
,
2000
),
"Wait for event_handle failed.
\n
"
);
CHECK_CALLED
(
uia_event_callback
);
hr
=
UiaRemoveEvent
(
event
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
...
...
@@ -14109,8 +14109,8 @@ static void test_UiaAddEvent_client_proc(void)
set_event_data
(
0
,
0
,
1
,
1
,
&
exp_node_desc
,
L"P)"
);
SET_EXPECT
(
uia_event_callback
);
post_event_message
(
hwnd
,
WM_UIA_TEST_RAISE_EVENT_RT_ID
,
0xbeef
,
PROVIDER2_ID
,
0x1337
);
todo_wine
ok
(
!
WaitForSingleObject
(
EventData
.
event_handle
,
2000
),
"Wait for event_handle failed.
\n
"
);
todo_wine
CHECK_CALLED
(
uia_event_callback
);
ok
(
!
WaitForSingleObject
(
EventData
.
event_handle
,
2000
),
"Wait for event_handle failed.
\n
"
);
CHECK_CALLED
(
uia_event_callback
);
hr
=
UiaRemoveEvent
(
event
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
...
...
dlls/uiautomationcore/uia_event.c
View file @
317d113a
...
...
@@ -267,13 +267,26 @@ static CRITICAL_SECTION_DEBUG event_thread_cs_debug =
};
static
CRITICAL_SECTION
event_thread_cs
=
{
&
event_thread_cs_debug
,
-
1
,
0
,
0
,
0
,
0
};
enum
uia_queue_event_type
{
QUEUE_EVENT_TYPE_SERVERSIDE
,
QUEUE_EVENT_TYPE_CLIENTSIDE
,
};
struct
uia_queue_event
{
struct
list
event_queue_entry
;
int
queue_event_type
;
struct
uia_event_args
*
args
;
struct
uia_event
*
event
;
HUIANODE
node
;
union
{
struct
{
HUIANODE
node
;
}
serverside
;
struct
{
LRESULT
node
;
}
clientside
;
}
u
;
};
static
void
uia_event_queue_push
(
struct
uia_queue_event
*
event
)
...
...
@@ -303,31 +316,73 @@ static struct uia_queue_event *uia_event_queue_pop(struct list *event_queue)
return
queue_event
;
}
static
HRESULT
uia_event_invoke
(
HUIANODE
node
,
struct
uia_event_args
*
args
,
struct
uia_event
*
event
);
static
HRESULT
uia_raise_clientside_event
(
struct
uia_queue_event
*
event
)
{
HUIANODE
node
;
HRESULT
hr
;
hr
=
uia_node_from_lresult
(
event
->
u
.
clientside
.
node
,
&
node
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
uia_event_invoke
(
node
,
event
->
args
,
event
->
event
);
UiaNodeRelease
(
node
);
}
return
hr
;
}
static
HRESULT
uia_raise_serverside_event
(
struct
uia_queue_event
*
event
)
{
HRESULT
hr
=
S_OK
;
LRESULT
lr
;
/*
* uia_lresult_from_node is expected to release the node here upon
* failure.
*/
if
((
lr
=
uia_lresult_from_node
(
event
->
u
.
serverside
.
node
)))
{
VARIANT
v
;
V_VT
(
&
v
)
=
VT_I4
;
V_I4
(
&
v
)
=
lr
;
hr
=
IWineUiaEvent_raise_event
(
event
->
event
->
u
.
serverside
.
event_iface
,
v
);
if
(
FAILED
(
hr
))
{
IWineUiaNode
*
node
;
/*
* If the method returned failure, make sure we don't leave a
* dangling IWineUiaNode.
*/
if
(
SUCCEEDED
(
ObjectFromLresult
(
lr
,
&
IID_IWineUiaNode
,
0
,
(
void
**
)
&
node
)))
IWineUiaNode_Release
(
node
);
}
}
else
hr
=
E_FAIL
;
return
hr
;
}
static
void
uia_event_thread_process_queue
(
struct
list
*
event_queue
)
{
while
(
1
)
{
struct
uia_queue_event
*
event
;
LRESULT
lr
;
HRESULT
hr
;
if
(
!
(
event
=
uia_event_queue_pop
(
event_queue
)))
break
;
/*
* uia_lresult_from_node is expected to release the node here upon
* failure.
*/
if
((
lr
=
uia_lresult_from_node
(
event
->
node
)))
{
VARIANT
v
;
if
(
event
->
queue_event_type
==
QUEUE_EVENT_TYPE_SERVERSIDE
)
hr
=
uia_raise_serverside_event
(
event
);
else
hr
=
uia_raise_clientside_event
(
event
);
V_VT
(
&
v
)
=
VT_I4
;
V_I4
(
&
v
)
=
lr
;
hr
=
IWineUiaEvent_raise_event
(
event
->
event
->
u
.
serverside
.
event_iface
,
v
);
if
(
FAILED
(
hr
))
WARN
(
"IWineUiaEvent_raise_event failed with hr %#lx
\n
"
,
hr
);
}
if
(
FAILED
(
hr
))
WARN
(
"Failed to raise event type %d with hr %#lx
\n
"
,
event
->
queue_event_type
,
hr
);
uia_event_args_release
(
event
->
args
);
IWineUiaEvent_Release
(
&
event
->
event
->
IWineUiaEvent_iface
);
...
...
@@ -583,18 +638,30 @@ static HRESULT WINAPI uia_event_set_event_data(IWineUiaEvent *iface, const GUID
static
HRESULT
WINAPI
uia_event_raise_event
(
IWineUiaEvent
*
iface
,
VARIANT
in_node
)
{
struct
uia_event
*
event
=
impl_from_IWineUiaEvent
(
iface
);
HUIANODE
node
;
HRESULT
hr
;
struct
uia_queue_event
*
queue_event
;
struct
uia_event_args
*
args
;
FIXME
(
"%p, %s: stub
\n
"
,
iface
,
debugstr_variant
(
&
in_node
));
TRACE
(
"%p, %s
\n
"
,
iface
,
debugstr_variant
(
&
in_node
));
assert
(
event
->
event_type
!=
EVENT_TYPE_SERVERSIDE
);
hr
=
uia_node_from_lresult
((
LRESULT
)
V_I4
(
&
in_node
),
&
node
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
!
(
queue_event
=
heap_alloc_zero
(
sizeof
(
*
queue_event
))))
return
E_OUTOFMEMORY
;
if
(
!
(
args
=
create_uia_event_args
(
uia_event_info_from_id
(
event
->
event_id
))))
{
heap_free
(
queue_event
);
return
E_OUTOFMEMORY
;
}
queue_event
->
queue_event_type
=
QUEUE_EVENT_TYPE_CLIENTSIDE
;
queue_event
->
args
=
args
;
queue_event
->
event
=
event
;
queue_event
->
u
.
clientside
.
node
=
V_I4
(
&
in_node
);
IWineUiaEvent_AddRef
(
&
event
->
IWineUiaEvent_iface
);
uia_event_queue_push
(
queue_event
);
UiaNodeRelease
(
node
);
return
S_OK
;
}
...
...
@@ -1159,9 +1226,10 @@ static HRESULT uia_event_invoke(HUIANODE node, struct uia_event_args *args, stru
return
hr
;
}
queue_event
->
queue_event_type
=
QUEUE_EVENT_TYPE_SERVERSIDE
;
queue_event
->
args
=
args
;
queue_event
->
event
=
event
;
queue_event
->
node
=
node2
;
queue_event
->
u
.
serverside
.
node
=
node2
;
InterlockedIncrement
(
&
args
->
ref
);
IWineUiaEvent_AddRef
(
&
event
->
IWineUiaEvent_iface
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment