Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
1122fde4
Commit
1122fde4
authored
May 10, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Jun 05, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Respect ProviderOptions_UseComThreading on advise events interfaces.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
68aa92d6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
151 additions
and
12 deletions
+151
-12
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+1
-1
uia_classes.idl
dlls/uiautomationcore/uia_classes.idl
+10
-0
uia_event.c
dlls/uiautomationcore/uia_event.c
+139
-10
uia_private.h
dlls/uiautomationcore/uia_private.h
+1
-1
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
1122fde4
...
...
@@ -13810,7 +13810,7 @@ static DWORD WINAPI uia_add_event_test_thread(LPVOID param)
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
Provider
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Provider
.
ref
);
ok
(
Provider2
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Provider2
.
ref
);
todo_wine
ok
(
Provider2
.
last_call_tid
==
data
->
exp_thread_id
||
ok
(
Provider2
.
last_call_tid
==
data
->
exp_thread_id
||
broken
(
Provider2
.
last_call_tid
==
GetCurrentThreadId
()),
"Expected method call on separate thread
\n
"
);
ok
(
Provider2
.
advise_events_removed_event_id
==
UIA_AutomationFocusChangedEventId
,
"Unexpected advise event removed, event ID %d
\n
"
,
Provider
.
advise_events_removed_event_id
);
...
...
dlls/uiautomationcore/uia_classes.idl
View file @
1122fde4
...
...
@@ -56,6 +56,16 @@ library UIA_wine_private
[
object
,
uuid
(
9
a754e12
-
e570
-
49
ab
-
b223
-
6
f6871007d28
),
pointer_default
(
unique
),
]
interface
IWineUiaEventAdviser
:
IUnknown
{
HRESULT
advise
(
[
in
]
BOOL
advise_added
,
[
in
]
LONG_PTR
huiaevent
)
;
}
[
object
,
uuid
(
5
e60162c
-
ab0e
-
4
e22
-
a61d
-
3
a3acd442aba
),
pointer_default
(
unique
),
]
...
...
dlls/uiautomationcore/uia_event.c
View file @
1122fde4
...
...
@@ -63,7 +63,7 @@ static ULONG WINAPI uia_event_Release(IWineUiaEvent *iface)
SafeArrayDestroy
(
event
->
runtime_id
);
for
(
i
=
0
;
i
<
event
->
event_advisers_count
;
i
++
)
I
RawElementProviderAdviseEvents
_Release
(
event
->
event_advisers
[
i
]);
I
WineUiaEventAdviser
_Release
(
event
->
event_advisers
[
i
]);
heap_free
(
event
->
event_advisers
);
heap_free
(
event
);
}
...
...
@@ -81,12 +81,7 @@ static HRESULT WINAPI uia_event_advise_events(IWineUiaEvent *iface, BOOL advise_
for
(
i
=
0
;
i
<
event
->
event_advisers_count
;
i
++
)
{
IRawElementProviderAdviseEvents
*
adviser
=
event
->
event_advisers
[
i
];
if
(
advise_added
)
hr
=
IRawElementProviderAdviseEvents_AdviseEventAdded
(
adviser
,
event
->
event_id
,
NULL
);
else
hr
=
IRawElementProviderAdviseEvents_AdviseEventRemoved
(
adviser
,
event
->
event_id
,
NULL
);
hr
=
IWineUiaEventAdviser_advise
(
event
->
event_advisers
[
i
],
advise_added
,
(
UINT_PTR
)
event
);
if
(
FAILED
(
hr
))
return
hr
;
}
...
...
@@ -95,7 +90,7 @@ static HRESULT WINAPI uia_event_advise_events(IWineUiaEvent *iface, BOOL advise_
if
(
!
advise_added
)
{
for
(
i
=
0
;
i
<
event
->
event_advisers_count
;
i
++
)
I
RawElementProviderAdviseEvents
_Release
(
event
->
event_advisers
[
i
]);
I
WineUiaEventAdviser
_Release
(
event
->
event_advisers
[
i
]);
heap_free
(
event
->
event_advisers
);
event
->
event_advisers_count
=
event
->
event_advisers_arr_size
=
0
;
}
...
...
@@ -138,14 +133,148 @@ static HRESULT create_uia_event(struct uia_event **out_event, int event_id, int
return
S_OK
;
}
/*
* IWineUiaEventAdviser interface.
*/
struct
uia_event_adviser
{
IWineUiaEventAdviser
IWineUiaEventAdviser_iface
;
LONG
ref
;
IRawElementProviderAdviseEvents
*
advise_events
;
DWORD
git_cookie
;
};
static
inline
struct
uia_event_adviser
*
impl_from_IWineUiaEventAdviser
(
IWineUiaEventAdviser
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
struct
uia_event_adviser
,
IWineUiaEventAdviser_iface
);
}
static
HRESULT
WINAPI
uia_event_adviser_QueryInterface
(
IWineUiaEventAdviser
*
iface
,
REFIID
riid
,
void
**
ppv
)
{
*
ppv
=
NULL
;
if
(
IsEqualIID
(
riid
,
&
IID_IWineUiaEventAdviser
)
||
IsEqualIID
(
riid
,
&
IID_IUnknown
))
*
ppv
=
iface
;
else
return
E_NOINTERFACE
;
IWineUiaEventAdviser_AddRef
(
iface
);
return
S_OK
;
}
static
ULONG
WINAPI
uia_event_adviser_AddRef
(
IWineUiaEventAdviser
*
iface
)
{
struct
uia_event_adviser
*
adv_events
=
impl_from_IWineUiaEventAdviser
(
iface
);
ULONG
ref
=
InterlockedIncrement
(
&
adv_events
->
ref
);
TRACE
(
"%p, refcount %ld
\n
"
,
adv_events
,
ref
);
return
ref
;
}
static
ULONG
WINAPI
uia_event_adviser_Release
(
IWineUiaEventAdviser
*
iface
)
{
struct
uia_event_adviser
*
adv_events
=
impl_from_IWineUiaEventAdviser
(
iface
);
ULONG
ref
=
InterlockedDecrement
(
&
adv_events
->
ref
);
TRACE
(
"%p, refcount %ld
\n
"
,
adv_events
,
ref
);
if
(
!
ref
)
{
if
(
adv_events
->
git_cookie
)
{
if
(
FAILED
(
unregister_interface_in_git
(
adv_events
->
git_cookie
)))
WARN
(
"Failed to revoke advise events interface from GIT
\n
"
);
}
IRawElementProviderAdviseEvents_Release
(
adv_events
->
advise_events
);
heap_free
(
adv_events
);
}
return
ref
;
}
static
HRESULT
WINAPI
uia_event_adviser_advise
(
IWineUiaEventAdviser
*
iface
,
BOOL
advise_added
,
LONG_PTR
huiaevent
)
{
struct
uia_event_adviser
*
adv_events
=
impl_from_IWineUiaEventAdviser
(
iface
);
struct
uia_event
*
event_data
=
(
struct
uia_event
*
)
huiaevent
;
IRawElementProviderAdviseEvents
*
advise_events
;
HRESULT
hr
;
TRACE
(
"%p, %d, %#Ix
\n
"
,
adv_events
,
advise_added
,
huiaevent
);
if
(
adv_events
->
git_cookie
)
{
hr
=
get_interface_in_git
(
&
IID_IRawElementProviderAdviseEvents
,
adv_events
->
git_cookie
,
(
IUnknown
**
)
&
advise_events
);
if
(
FAILED
(
hr
))
return
hr
;
}
else
{
advise_events
=
adv_events
->
advise_events
;
IRawElementProviderAdviseEvents_AddRef
(
advise_events
);
}
if
(
advise_added
)
hr
=
IRawElementProviderAdviseEvents_AdviseEventAdded
(
advise_events
,
event_data
->
event_id
,
NULL
);
else
hr
=
IRawElementProviderAdviseEvents_AdviseEventRemoved
(
advise_events
,
event_data
->
event_id
,
NULL
);
IRawElementProviderAdviseEvents_Release
(
advise_events
);
return
hr
;
}
static
const
IWineUiaEventAdviserVtbl
uia_event_adviser_vtbl
=
{
uia_event_adviser_QueryInterface
,
uia_event_adviser_AddRef
,
uia_event_adviser_Release
,
uia_event_adviser_advise
,
};
HRESULT
uia_event_add_provider_event_adviser
(
IRawElementProviderAdviseEvents
*
advise_events
,
struct
uia_event
*
event
)
{
struct
uia_event_adviser
*
adv_events
;
IRawElementProviderSimple
*
elprov
;
enum
ProviderOptions
prov_opts
;
HRESULT
hr
;
hr
=
IRawElementProviderAdviseEvents_QueryInterface
(
advise_events
,
&
IID_IRawElementProviderSimple
,
(
void
**
)
&
elprov
);
if
(
FAILED
(
hr
))
{
ERR
(
"Failed to get IRawElementProviderSimple from advise events
\n
"
);
return
E_FAIL
;
}
hr
=
IRawElementProviderSimple_get_ProviderOptions
(
elprov
,
&
prov_opts
);
IRawElementProviderSimple_Release
(
elprov
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
!
(
adv_events
=
heap_alloc_zero
(
sizeof
(
*
adv_events
))))
return
E_OUTOFMEMORY
;
if
(
prov_opts
&
ProviderOptions_UseComThreading
)
{
hr
=
register_interface_in_git
((
IUnknown
*
)
advise_events
,
&
IID_IRawElementProviderAdviseEvents
,
&
adv_events
->
git_cookie
);
if
(
FAILED
(
hr
))
{
heap_free
(
adv_events
);
return
hr
;
}
}
adv_events
->
IWineUiaEventAdviser_iface
.
lpVtbl
=
&
uia_event_adviser_vtbl
;
adv_events
->
ref
=
1
;
adv_events
->
advise_events
=
advise_events
;
IRawElementProviderAdviseEvents_AddRef
(
advise_events
);
if
(
!
uia_array_reserve
((
void
**
)
&
event
->
event_advisers
,
&
event
->
event_advisers_arr_size
,
event
->
event_advisers_count
+
1
,
sizeof
(
*
event
->
event_advisers
)))
{
IWineUiaEventAdviser_Release
(
&
adv_events
->
IWineUiaEventAdviser_iface
);
return
E_OUTOFMEMORY
;
}
event
->
event_advisers
[
event
->
event_advisers_count
]
=
advise_events
;
IRawElementProviderAdviseEvents_AddRef
(
advise_events
);
event
->
event_advisers
[
event
->
event_advisers_count
]
=
&
adv_events
->
IWineUiaEventAdviser_iface
;
event
->
event_advisers_count
++
;
return
S_OK
;
...
...
dlls/uiautomationcore/uia_private.h
View file @
1122fde4
...
...
@@ -102,7 +102,7 @@ struct uia_event
int
event_id
;
int
scope
;
I
RawElementProviderAdviseEvents
**
event_advisers
;
I
WineUiaEventAdviser
**
event_advisers
;
int
event_advisers_count
;
SIZE_T
event_advisers_arr_size
;
...
...
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