ReactOS 0.4.16-dev-2491-g3dc6630
uia_event.c File Reference
#include "uia_private.h"
#include "wine/debug.h"
#include "wine/rbtree.h"
Include dependency graph for uia_event.c:

Go to the source code of this file.

Classes

struct  uia_event_map
 
struct  uia_event_map_entry
 
struct  uia_event_identifier
 
struct  event_sink_event
 
struct  uia_proxy_win_event_sink
 
struct  uia_event_thread
 
struct  uia_queue_event
 
struct  uia_queue_uia_event
 
struct  uia_queue_win_event
 
struct  uia_elprov_event_data
 
struct  uia_event_adviser
 
struct  uia_serverside_event_adviser
 

Macros

#define WM_UIA_EVENT_THREAD_STOP   (WM_USER + 1)
 
#define WM_UIA_EVENT_THREAD_PROCESS_QUEUE   (WM_USER + 2)
 

Enumerations

enum  uia_queue_event_type { QUEUE_EVENT_TYPE_SERVERSIDE , QUEUE_EVENT_TYPE_CLIENTSIDE , QUEUE_EVENT_TYPE_WIN_EVENT }
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (uiautomation)
 
static BOOL WINAPI uia_init_desktop_rt_id (INIT_ONCE *once, void *param, void **ctx)
 
static SAFEARRAYuia_get_desktop_rt_id (void)
 
static int win_event_to_uia_event_id (int win_event)
 
static BOOL CALLBACK uia_win_event_enum_top_level_hwnds (HWND hwnd, LPARAM lparam)
 
HRESULT uia_event_add_win_event_hwnd (struct uia_event *event, HWND hwnd)
 
static int uia_serverside_event_id_compare (const void *key, const struct rb_entry *entry)
 
static int uia_event_map_id_compare (const void *key, const struct rb_entry *entry)
 
static struct uia_event_map_entryuia_get_event_map_entry_for_event (int event_id)
 
static HRESULT uia_event_map_add_event (struct uia_event *event)
 
static void uia_event_map_entry_release (struct uia_event_map_entry *entry)
 
HRESULT uia_event_for_each (int event_id, UiaWineEventForEachCallback *callback, void *user_data, BOOL clientside_only)
 
static struct uia_event_argscreate_uia_event_args (const struct uia_event_info *event_info)
 
static void uia_event_args_release (struct uia_event_args *args)
 
static HRESULT uia_event_sink_list_add_event (struct list *sink_events, IRawElementProviderSimple *elprov, struct uia_event_args *args)
 
static struct uia_proxy_win_event_sinkimpl_from_IProxyProviderWinEventSink (IProxyProviderWinEventSink *iface)
 
static HRESULT WINAPI uia_proxy_win_event_sink_QueryInterface (IProxyProviderWinEventSink *iface, REFIID riid, void **obj)
 
static ULONG WINAPI uia_proxy_win_event_sink_AddRef (IProxyProviderWinEventSink *iface)
 
static ULONG WINAPI uia_proxy_win_event_sink_Release (IProxyProviderWinEventSink *iface)
 
static HRESULT WINAPI uia_proxy_win_event_sink_AddAutomationPropertyChangedEvent (IProxyProviderWinEventSink *iface, IRawElementProviderSimple *elprov, PROPERTYID prop_id, VARIANT new_value)
 
static HRESULT WINAPI uia_proxy_win_event_sink_AddAutomationEvent (IProxyProviderWinEventSink *iface, IRawElementProviderSimple *elprov, EVENTID event_id)
 
static HRESULT WINAPI uia_proxy_win_event_sink_AddStructureChangedEvent (IProxyProviderWinEventSink *iface, IRawElementProviderSimple *elprov, enum StructureChangeType structure_change_type, SAFEARRAY *runtime_id)
 
static HRESULT create_proxy_win_event_sink (struct uia_proxy_win_event_sink **out_sink, int event_id)
 
static void uia_event_queue_push (struct uia_queue_event *event, int queue_event_type)
 
static struct uia_queue_eventuia_event_queue_pop (struct list *event_queue)
 
static HRESULT uia_raise_clientside_event (struct uia_queue_uia_event *event)
 
static HRESULT uia_raise_serverside_event (struct uia_queue_uia_event *event)
 
static BOOL uia_win_event_hwnd_map_contains_ancestors (struct rb_tree *hwnd_map, HWND hwnd)
 
HRESULT create_msaa_provider_from_hwnd (HWND hwnd, int in_child_id, IRawElementProviderSimple **ret_elprov)
 
static HRESULT uia_raise_elprov_event_callback (struct uia_event *event, void *data)
 
static HRESULT uia_win_event_for_each_callback (struct uia_event *event, void *data)
 
static void uia_event_thread_process_queue (struct list *event_queue)
 
static void CALLBACK uia_event_thread_win_event_proc (HWINEVENTHOOK hook, DWORD event_id, HWND hwnd, LONG obj_id, LONG child_id, DWORD thread_id, DWORD event_time)
 
static DWORD WINAPI uia_event_thread_proc (void *arg)
 
static BOOL uia_start_event_thread (void)
 
static void uia_stop_event_thread (void)
 
BOOL uia_clientside_event_start_event_thread (struct uia_event *event)
 
static void uia_event_clear_advisers (struct uia_event *event)
 
static struct uia_eventimpl_from_IWineUiaEvent (IWineUiaEvent *iface)
 
static HRESULT WINAPI uia_event_QueryInterface (IWineUiaEvent *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI uia_event_AddRef (IWineUiaEvent *iface)
 
static ULONG WINAPI uia_event_Release (IWineUiaEvent *iface)
 
static HRESULT WINAPI uia_event_advise_events (IWineUiaEvent *iface, BOOL advise_added, LONG adviser_start_idx)
 
static HRESULT WINAPI uia_event_set_event_data (IWineUiaEvent *iface, const GUID *event_guid, LONG scope, VARIANT runtime_id, IWineUiaEvent *event_iface)
 
static HRESULT WINAPI uia_event_raise_event (IWineUiaEvent *iface, VARIANT in_node, VARIANT in_nav_start_node)
 
static struct uia_eventunsafe_impl_from_IWineUiaEvent (IWineUiaEvent *iface)
 
static HRESULT create_uia_event (struct uia_event **out_event, LONG event_cookie, int event_type)
 
static HRESULT create_clientside_uia_event (struct uia_event **out_event, int event_id, int scope, UiaWineEventCallback *cback, void *cback_data, SAFEARRAY *runtime_id)
 
HRESULT create_serverside_uia_event (struct uia_event **out_event, LONG process_id, LONG event_cookie)
 
static HRESULT uia_event_add_event_adviser (IWineUiaEventAdviser *adviser, struct uia_event *event)
 
static struct uia_event_adviserimpl_from_IWineUiaEventAdviser (IWineUiaEventAdviser *iface)
 
static HRESULT WINAPI uia_event_adviser_QueryInterface (IWineUiaEventAdviser *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI uia_event_adviser_AddRef (IWineUiaEventAdviser *iface)
 
static ULONG WINAPI uia_event_adviser_Release (IWineUiaEventAdviser *iface)
 
static HRESULT WINAPI uia_event_adviser_advise (IWineUiaEventAdviser *iface, BOOL advise_added, LONG_PTR huiaevent)
 
HRESULT uia_event_add_provider_event_adviser (IRawElementProviderAdviseEvents *advise_events, struct uia_event *event)
 
static struct uia_serverside_event_adviserimpl_from_serverside_IWineUiaEventAdviser (IWineUiaEventAdviser *iface)
 
static HRESULT WINAPI uia_serverside_event_adviser_QueryInterface (IWineUiaEventAdviser *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI uia_serverside_event_adviser_AddRef (IWineUiaEventAdviser *iface)
 
static ULONG WINAPI uia_serverside_event_adviser_Release (IWineUiaEventAdviser *iface)
 
static HRESULT WINAPI uia_serverside_event_adviser_advise (IWineUiaEventAdviser *iface, BOOL advise_added, LONG_PTR huiaevent)
 
HRESULT uia_event_add_serverside_event_adviser (IWineUiaEvent *serverside_event, struct uia_event *event)
 
static HRESULT uia_event_advise (struct uia_event *event, BOOL advise_added, LONG start_idx)
 
HRESULT uia_event_advise_node (struct uia_event *event, HUIANODE node)
 
HRESULT WINAPI UiaEventAddWindow (HUIAEVENT huiaevent, HWND hwnd)
 
static HRESULT uia_clientside_event_callback (struct uia_event *event, struct uia_event_args *args, SAFEARRAY *cache_req, BSTR tree_struct)
 
HRESULT uia_add_clientside_event (HUIANODE huianode, EVENTID event_id, enum TreeScope scope, PROPERTYID *prop_ids, int prop_ids_count, struct UiaCacheRequest *cache_req, SAFEARRAY *rt_id, UiaWineEventCallback *cback, void *cback_data, HUIAEVENT *huiaevent)
 
HRESULT WINAPI UiaAddEvent (HUIANODE huianode, EVENTID event_id, UiaEventCallback *callback, enum TreeScope scope, PROPERTYID *prop_ids, int prop_ids_count, struct UiaCacheRequest *cache_req, HUIAEVENT *huiaevent)
 
HRESULT WINAPI UiaRemoveEvent (HUIAEVENT huiaevent)
 
HRESULT uia_event_invoke (HUIANODE node, HUIANODE nav_start_node, struct uia_event_args *args, struct uia_event *event)
 
static void set_refuse_hwnd_providers (struct uia_node *node, BOOL refuse_hwnd_providers)
 
HRESULT uia_event_check_node_within_event_scope (struct uia_event *event, HUIANODE node, SAFEARRAY *rt_id, HUIANODE *clientside_nav_node_out)
 
static HRESULT uia_raise_elprov_event (IRawElementProviderSimple *elprov, struct uia_event_args *args)
 
HRESULT WINAPI UiaRaiseAutomationEvent (IRawElementProviderSimple *elprov, EVENTID id)
 

Variables

static SAFEARRAYuia_desktop_node_rt_id
 
static struct uia_event_map uia_event_map
 
static CRITICAL_SECTION event_map_cs = { &event_map_cs_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG event_map_cs_debug
 
static const IProxyProviderWinEventSinkVtbl uia_proxy_event_sink_vtbl
 
static struct uia_event_thread event_thread
 
static CRITICAL_SECTION event_thread_cs = { &event_thread_cs_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG event_thread_cs_debug
 
static const IWineUiaEventVtbl uia_event_vtbl
 
static const IWineUiaEventAdviserVtbl uia_event_adviser_vtbl
 
static const IWineUiaEventAdviserVtbl uia_serverside_event_adviser_vtbl
 

Macro Definition Documentation

◆ WM_UIA_EVENT_THREAD_PROCESS_QUEUE

#define WM_UIA_EVENT_THREAD_PROCESS_QUEUE   (WM_USER + 2)

Definition at line 496 of file uia_event.c.

◆ WM_UIA_EVENT_THREAD_STOP

#define WM_UIA_EVENT_THREAD_STOP   (WM_USER + 1)

Definition at line 495 of file uia_event.c.

Enumeration Type Documentation

◆ uia_queue_event_type

Enumerator
QUEUE_EVENT_TYPE_SERVERSIDE 
QUEUE_EVENT_TYPE_CLIENTSIDE 
QUEUE_EVENT_TYPE_WIN_EVENT 

Definition at line 507 of file uia_event.c.

507 {
511};
@ QUEUE_EVENT_TYPE_SERVERSIDE
Definition: uia_event.c:508
@ QUEUE_EVENT_TYPE_WIN_EVENT
Definition: uia_event.c:510
@ QUEUE_EVENT_TYPE_CLIENTSIDE
Definition: uia_event.c:509

Function Documentation

◆ create_clientside_uia_event()

static HRESULT create_clientside_uia_event ( struct uia_event **  out_event,
int  event_id,
int  scope,
UiaWineEventCallback cback,
void cback_data,
SAFEARRAY runtime_id 
)
static

Definition at line 1211 of file uia_event.c.

1213{
1214 struct uia_event *event = NULL;
1215 static LONG next_event_cookie;
1216 HRESULT hr;
1217
1218 *out_event = NULL;
1220 if (FAILED(hr))
1221 return hr;
1222
1223 event->runtime_id = runtime_id;
1224 event->event_id = event_id;
1225 event->scope = scope;
1226 event->u.clientside.event_callback = cback;
1227 event->u.clientside.callback_data = cback_data;
1228 uia_hwnd_map_init(&event->u.clientside.win_event_hwnd_map);
1229
1230 *out_event = event;
1231 return S_OK;
1232}
#define InterlockedIncrement
Definition: armddk.h:53
HRESULT hr
Definition: delayimp.cpp:573
#define NULL
Definition: types.h:112
struct _cl_event * event
Definition: glext.h:7739
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
long LONG
Definition: pedump.c:60
int event_id
Definition: uia_private.h:127
SAFEARRAY * runtime_id
Definition: uia_private.h:126
static HRESULT create_uia_event(struct uia_event **out_event, LONG event_cookie, int event_type)
Definition: uia_event.c:1194
void uia_hwnd_map_init(struct rb_tree *hwnd_map)
Definition: uia_utils.c:479
@ EVENT_TYPE_CLIENTSIDE
Definition: uia_private.h:116

Referenced by uia_add_clientside_event().

◆ create_msaa_provider_from_hwnd()

HRESULT create_msaa_provider_from_hwnd ( HWND  hwnd,
int  in_child_id,
IRawElementProviderSimple **  ret_elprov 
)

Definition at line 677 of file uia_event.c.

678{
679 IRawElementProviderSimple *elprov;
680 IAccessible *acc;
681 int child_id;
682 HRESULT hr;
683
684 *ret_elprov = NULL;
685 hr = AccessibleObjectFromWindow(hwnd, OBJID_CLIENT, &IID_IAccessible, (void **)&acc);
686 if (FAILED(hr))
687 return hr;
688
689 child_id = in_child_id;
690 if (in_child_id != CHILDID_SELF)
691 {
692 IDispatch *disp;
693 VARIANT cid;
694
695 disp = NULL;
696 variant_init_i4(&cid, in_child_id);
697 hr = IAccessible_get_accChild(acc, cid, &disp);
698 if (FAILED(hr))
699 TRACE("get_accChild failed with %#lx!\n", hr);
700
701 if (SUCCEEDED(hr) && disp)
702 {
703 IAccessible_Release(acc);
704 hr = IDispatch_QueryInterface(disp, &IID_IAccessible, (void **)&acc);
705 IDispatch_Release(disp);
706 if (FAILED(hr))
707 return hr;
708
709 child_id = CHILDID_SELF;
710 }
711 }
712
713 hr = create_msaa_provider(acc, child_id, hwnd, TRUE, in_child_id == CHILDID_SELF, &elprov);
714 IAccessible_Release(acc);
715 if (FAILED(hr))
716 return hr;
717
718 *ret_elprov = elprov;
719 return S_OK;
720}
#define TRUE
Definition: types.h:120
HRESULT WINAPI AccessibleObjectFromWindow(HWND hwnd, DWORD dwObjectID, REFIID riid, void **ppvObject)
Definition: main.c:349
static TfClientId cid
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT create_msaa_provider(IAccessible *acc, LONG child_id, HWND hwnd, BOOL root_acc_known, BOOL is_root_acc, IRawElementProviderSimple **elprov)
static void variant_init_i4(VARIANT *v, int val)
Definition: uia_private.h:169
#define OBJID_CLIENT
Definition: winable.h:19
#define CHILDID_SELF
Definition: winable.h:14
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023

Referenced by uia_com_focus_win_event_msaa_handler(), and uia_win_event_for_each_callback().

◆ create_proxy_win_event_sink()

static HRESULT create_proxy_win_event_sink ( struct uia_proxy_win_event_sink **  out_sink,
int  event_id 
)
static

Definition at line 457 of file uia_event.c.

458{
459 struct uia_proxy_win_event_sink *sink = calloc(1, sizeof(*sink));
460 HRESULT hr;
461
462 *out_sink = NULL;
463 if (!sink)
464 return E_OUTOFMEMORY;
465
466 sink->IProxyProviderWinEventSink_iface.lpVtbl = &uia_proxy_event_sink_vtbl;
467 sink->ref = 1;
468 sink->event_id = event_id;
469 list_init(&sink->sink_events);
470
471 hr = CoCreateFreeThreadedMarshaler((IUnknown *)&sink->IProxyProviderWinEventSink_iface, &sink->marshal);
472 if (FAILED(hr))
473 {
474 free(sink);
475 return hr;
476 }
477
478 *out_sink = sink;
479 return S_OK;
480}
static void list_init(struct list_entry *head)
Definition: list.h:51
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define free
Definition: debug_ros.c:5
HRESULT WINAPI CoCreateFreeThreadedMarshaler(IUnknown *outer, IUnknown **marshaler)
Definition: marshal.c:417
GLsizei GLenum GLboolean sink
Definition: glext.h:5672
#define calloc
Definition: rosglue.h:14
static const IProxyProviderWinEventSinkVtbl uia_proxy_event_sink_vtbl
Definition: uia_event.c:448

Referenced by uia_win_event_for_each_callback().

◆ create_serverside_uia_event()

HRESULT create_serverside_uia_event ( struct uia_event **  out_event,
LONG  process_id,
LONG  event_cookie 
)

Definition at line 1234 of file uia_event.c.

1235{
1236 struct uia_event_identifier event_identifier = { event_cookie, process_id };
1237 struct rb_entry *rb_entry;
1238 struct uia_event *event;
1239 HRESULT hr = S_OK;
1240
1241 /*
1242 * Attempt to lookup an existing event for this PID/event_cookie. If there
1243 * is one, return S_FALSE.
1244 */
1245 *out_event = NULL;
1248 {
1249 *out_event = RB_ENTRY_VALUE(rb_entry, struct uia_event, u.serverside.serverside_event_entry);
1250 hr = S_FALSE;
1251 goto exit;
1252 }
1253
1255 if (FAILED(hr))
1256 goto exit;
1257
1259 {
1260 free(event);
1261 hr = E_FAIL;
1262 goto exit;
1263 }
1264
1265 event->u.serverside.proc_id = process_id;
1269 rb_put(&uia_event_map.serverside_event_map, &event_identifier, &event->u.serverside.serverside_event_entry);
1270 *out_event = event;
1271
1272exit:
1274 return hr;
1275}
#define E_FAIL
Definition: ddrawi.h:102
#define rb_entry(ptr, type, member)
Definition: rbtree.h:130
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define RB_ENTRY_VALUE(element, type, field)
Definition: rbtree.h:26
static int rb_put(struct rb_tree *tree, const void *key, struct rb_entry *entry)
Definition: rbtree.h:204
static struct rb_entry * rb_get(const struct rb_tree *tree, const void *key)
Definition: rbtree.h:192
static void rb_init(struct rb_tree *tree, rb_compare_func_t compare)
Definition: rbtree.h:173
#define exit(n)
Definition: config.h:202
Definition: rbtree.h:30
LONG serverside_event_count
Definition: uia_event.c:104
struct rb_tree serverside_event_map
Definition: uia_event.c:103
LONG event_cookie
Definition: uia_private.h:138
static CRITICAL_SECTION event_map_cs
Definition: uia_event.c:142
static int uia_serverside_event_id_compare(const void *key, const struct rb_entry *entry)
Definition: uia_event.c:131
static BOOL uia_start_event_thread(void)
Definition: uia_event.c:932
@ EVENT_TYPE_SERVERSIDE
Definition: uia_private.h:117
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define S_FALSE
Definition: winerror.h:3451

Referenced by uia_node_attach_event().

◆ create_uia_event()

static HRESULT create_uia_event ( struct uia_event **  out_event,
LONG  event_cookie,
int  event_type 
)
static

Definition at line 1194 of file uia_event.c.

1195{
1196 struct uia_event *event = calloc(1, sizeof(*event));
1197
1198 *out_event = NULL;
1199 if (!event)
1200 return E_OUTOFMEMORY;
1201
1202 event->IWineUiaEvent_iface.lpVtbl = &uia_event_vtbl;
1203 event->ref = 1;
1204 event->event_cookie = event_cookie;
1205 event->event_type = event_type;
1206 *out_event = event;
1207
1208 return S_OK;
1209}
int event_type
Definition: uia_private.h:139
static const IWineUiaEventVtbl uia_event_vtbl
Definition: uia_event.c:1177

Referenced by create_clientside_uia_event(), and create_serverside_uia_event().

◆ create_uia_event_args()

static struct uia_event_args * create_uia_event_args ( const struct uia_event_info event_info)
static

Definition at line 305 of file uia_event.c.

306{
307 struct uia_event_args *args = calloc(1, sizeof(*args));
308
309 if (!args)
310 return NULL;
311
312 args->simple_args.Type = event_info->event_arg_type;
313 args->simple_args.EventId = event_info->event_id;
314 args->ref = 1;
315
316 return args;
317}
static const event_info_t event_info[]
Definition: htmlevent.c:154
#define args
Definition: format.c:66
Definition: match.c:390

Referenced by uia_event_raise_event(), uia_proxy_win_event_sink_AddAutomationEvent(), and UiaRaiseAutomationEvent().

◆ impl_from_IProxyProviderWinEventSink()

static struct uia_proxy_win_event_sink * impl_from_IProxyProviderWinEventSink ( IProxyProviderWinEventSink *  iface)
inlinestatic

Definition at line 364 of file uia_event.c.

365{
366 return CONTAINING_RECORD(iface, struct uia_proxy_win_event_sink, IProxyProviderWinEventSink_iface);
367}
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by uia_proxy_win_event_sink_AddAutomationEvent(), uia_proxy_win_event_sink_AddRef(), uia_proxy_win_event_sink_QueryInterface(), and uia_proxy_win_event_sink_Release().

◆ impl_from_IWineUiaEvent()

static struct uia_event * impl_from_IWineUiaEvent ( IWineUiaEvent *  iface)
inlinestatic

Definition at line 1010 of file uia_event.c.

1011{
1012 return CONTAINING_RECORD(iface, struct uia_event, IWineUiaEvent_iface);
1013}

Referenced by uia_event_AddRef(), uia_event_advise_events(), uia_event_raise_event(), uia_event_Release(), and uia_event_set_event_data().

◆ impl_from_IWineUiaEventAdviser()

static struct uia_event_adviser * impl_from_IWineUiaEventAdviser ( IWineUiaEventAdviser *  iface)
inlinestatic

Definition at line 1301 of file uia_event.c.

1302{
1303 return CONTAINING_RECORD(iface, struct uia_event_adviser, IWineUiaEventAdviser_iface);
1304}

Referenced by uia_event_adviser_AddRef(), uia_event_adviser_advise(), and uia_event_adviser_Release().

◆ impl_from_serverside_IWineUiaEventAdviser()

static struct uia_serverside_event_adviser * impl_from_serverside_IWineUiaEventAdviser ( IWineUiaEventAdviser *  iface)
inlinestatic

◆ set_refuse_hwnd_providers()

static void set_refuse_hwnd_providers ( struct uia_node node,
BOOL  refuse_hwnd_providers 
)
static

Definition at line 1801 of file uia_event.c.

1802{
1804
1805 prov_data->refuse_hwnd_node_providers = refuse_hwnd_providers;
1806}
BOOL refuse_hwnd_node_providers
Definition: uia_private.h:97
int get_node_provider_type_at_idx(struct uia_node *node, int idx)
Definition: uia_client.c:266
static struct uia_provider * impl_from_IWineUiaProvider(IWineUiaProvider *iface)
Definition: uia_private.h:104
Definition: dlist.c:348

Referenced by uia_event_check_node_within_event_scope().

◆ uia_add_clientside_event()

HRESULT uia_add_clientside_event ( HUIANODE  huianode,
EVENTID  event_id,
enum TreeScope  scope,
PROPERTYID prop_ids,
int  prop_ids_count,
struct UiaCacheRequest cache_req,
SAFEARRAY rt_id,
UiaWineEventCallback cback,
void cback_data,
HUIAEVENT *  huiaevent 
)

Definition at line 1628 of file uia_event.c.

1631{
1632 struct uia_event *event;
1633 SAFEARRAY *sa;
1634 HRESULT hr;
1635
1636 hr = SafeArrayCopy(rt_id, &sa);
1637 if (FAILED(hr))
1638 return hr;
1639
1640 hr = create_clientside_uia_event(&event, event_id, scope, cback, cback_data, sa);
1641 if (FAILED(hr))
1642 {
1644 return hr;
1645 }
1646
1647 hr = uia_cache_request_clone(&event->u.clientside.cache_req, cache_req);
1648 if (FAILED(hr))
1649 goto exit;
1650
1651 hr = attach_event_to_uia_node(huianode, event);
1652 if (FAILED(hr))
1653 goto exit;
1654
1656 if (FAILED(hr))
1657 goto exit;
1658
1660 if (FAILED(hr))
1661 goto exit;
1662
1663 *huiaevent = (HUIAEVENT)event;
1664
1665exit:
1666 if (FAILED(hr))
1667 IWineUiaEvent_Release(&event->IWineUiaEvent_iface);
1668
1669 return hr;
1670}
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
HRESULT WINAPI SafeArrayCopy(SAFEARRAY *psa, SAFEARRAY **ppsaOut)
Definition: safearray.c:1379
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
struct UiaCacheRequest cache_req
Definition: uia_private.h:143
HRESULT attach_event_to_uia_node(HUIANODE node, struct uia_event *event)
Definition: uia_client.c:1337
static HRESULT uia_event_advise(struct uia_event *event, BOOL advise_added, LONG start_idx)
Definition: uia_event.c:1553
static HRESULT uia_event_map_add_event(struct uia_event *event)
Definition: uia_event.c:170
static HRESULT create_clientside_uia_event(struct uia_event **out_event, int event_id, int scope, UiaWineEventCallback *cback, void *cback_data, SAFEARRAY *runtime_id)
Definition: uia_event.c:1211
HRESULT uia_cache_request_clone(struct UiaCacheRequest *dst, struct UiaCacheRequest *src)
Definition: uia_utils.c:264

Referenced by uia_add_com_event_handler(), and UiaAddEvent().

◆ uia_clientside_event_callback()

static HRESULT uia_clientside_event_callback ( struct uia_event event,
struct uia_event_args args,
SAFEARRAY cache_req,
BSTR  tree_struct 
)
static

Definition at line 1618 of file uia_event.c.

1620{
1621 UiaEventCallback *event_callback = (UiaEventCallback *)event->u.clientside.callback_data;
1622
1623 event_callback(&args->simple_args, cache_req, tree_struct);
1624
1625 return S_OK;
1626}
void WINAPI UiaEventCallback(struct UiaEventArgs *pArgs, SAFEARRAY *pRequestedData, BSTR pTreeStructure)

Referenced by UiaAddEvent().

◆ uia_clientside_event_start_event_thread()

BOOL uia_clientside_event_start_event_thread ( struct uia_event event)

Definition at line 988 of file uia_event.c.

989{
990 if (!event->u.clientside.event_thread_started)
991 event->u.clientside.event_thread_started = uia_start_event_thread();
992
993 return event->u.clientside.event_thread_started;
994}

Referenced by uia_add_com_event_handler(), uia_event_add_serverside_event_adviser(), and uia_event_add_win_event_hwnd().

◆ uia_event_add_event_adviser()

static HRESULT uia_event_add_event_adviser ( IWineUiaEventAdviser *  adviser,
struct uia_event event 
)
static

Definition at line 1277 of file uia_event.c.

1278{
1279 if (!uia_array_reserve((void **)&event->event_advisers, &event->event_advisers_arr_size,
1280 event->event_advisers_count + 1, sizeof(*event->event_advisers)))
1281 return E_OUTOFMEMORY;
1282
1283 event->event_advisers[event->event_advisers_count] = adviser;
1284 IWineUiaEventAdviser_AddRef(adviser);
1285 event->event_advisers_count++;
1286
1287 return S_OK;
1288}
static BOOL uia_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
Definition: uia_private.h:186

Referenced by uia_event_add_provider_event_adviser(), and uia_event_add_serverside_event_adviser().

◆ uia_event_add_provider_event_adviser()

HRESULT uia_event_add_provider_event_adviser ( IRawElementProviderAdviseEvents *  advise_events,
struct uia_event event 
)

Definition at line 1385 of file uia_event.c.

1386{
1387 struct uia_event_adviser *adv_events;
1388 IRawElementProviderSimple *elprov;
1389 enum ProviderOptions prov_opts;
1390 HRESULT hr;
1391
1392 hr = IRawElementProviderAdviseEvents_QueryInterface(advise_events, &IID_IRawElementProviderSimple,
1393 (void **)&elprov);
1394 if (FAILED(hr))
1395 {
1396 ERR("Failed to get IRawElementProviderSimple from advise events\n");
1397 return E_FAIL;
1398 }
1399
1400 hr = IRawElementProviderSimple_get_ProviderOptions(elprov, &prov_opts);
1401 IRawElementProviderSimple_Release(elprov);
1402 if (FAILED(hr))
1403 return hr;
1404
1405 if (!(adv_events = calloc(1, sizeof(*adv_events))))
1406 return E_OUTOFMEMORY;
1407
1408 if (prov_opts & ProviderOptions_UseComThreading)
1409 {
1410 hr = register_interface_in_git((IUnknown *)advise_events, &IID_IRawElementProviderAdviseEvents,
1411 &adv_events->git_cookie);
1412 if (FAILED(hr))
1413 {
1414 free(adv_events);
1415 return hr;
1416 }
1417 }
1418
1420 adv_events->ref = 1;
1421 adv_events->advise_events = advise_events;
1422 IRawElementProviderAdviseEvents_AddRef(advise_events);
1423
1425 IWineUiaEventAdviser_Release(&adv_events->IWineUiaEventAdviser_iface);
1426
1427 return hr;
1428}
#define ERR(fmt,...)
Definition: precomp.h:57
IRawElementProviderAdviseEvents * advise_events
Definition: uia_event.c:1297
IWineUiaEventAdviser IWineUiaEventAdviser_iface
Definition: uia_event.c:1294
static const IWineUiaEventAdviserVtbl uia_event_adviser_vtbl
Definition: uia_event.c:1378
static HRESULT uia_event_add_event_adviser(IWineUiaEventAdviser *adviser, struct uia_event *event)
Definition: uia_event.c:1277
HRESULT register_interface_in_git(IUnknown *iface, REFIID riid, DWORD *ret_cookie)
Definition: uia_utils.c:40
ProviderOptions
@ ProviderOptions_UseComThreading

Referenced by uia_provider_attach_event().

◆ uia_event_add_serverside_event_adviser()

HRESULT uia_event_add_serverside_event_adviser ( IWineUiaEvent *  serverside_event,
struct uia_event event 
)

Definition at line 1519 of file uia_event.c.

1520{
1521 struct uia_serverside_event_adviser *adv_events;
1522 HRESULT hr;
1523
1524 /*
1525 * Need to create a proxy IWineUiaEvent for our clientside event to use
1526 * this serverside IWineUiaEvent proxy from the appropriate apartment.
1527 */
1528 if (!event->u.clientside.git_cookie)
1529 {
1531 return E_FAIL;
1532
1533 hr = register_interface_in_git((IUnknown *)&event->IWineUiaEvent_iface, &IID_IWineUiaEvent,
1534 &event->u.clientside.git_cookie);
1535 if (FAILED(hr))
1536 return hr;
1537 }
1538
1539 if (!(adv_events = calloc(1, sizeof(*adv_events))))
1540 return E_OUTOFMEMORY;
1541
1543 adv_events->ref = 1;
1544 adv_events->event_iface = serverside_event;
1545 IWineUiaEvent_AddRef(serverside_event);
1546
1548 IWineUiaEventAdviser_Release(&adv_events->IWineUiaEventAdviser_iface);
1549
1550 return hr;
1551}
IWineUiaEventAdviser IWineUiaEventAdviser_iface
Definition: uia_event.c:1434
IWineUiaEvent * event_iface
Definition: uia_event.c:1437
BOOL uia_clientside_event_start_event_thread(struct uia_event *event)
Definition: uia_event.c:988
static const IWineUiaEventAdviserVtbl uia_serverside_event_adviser_vtbl
Definition: uia_event.c:1512

Referenced by uia_nested_node_provider_attach_event().

◆ uia_event_add_win_event_hwnd()

HRESULT uia_event_add_win_event_hwnd ( struct uia_event event,
HWND  hwnd 
)

Definition at line 83 of file uia_event.c.

84{
86 return E_FAIL;
87
88 if (hwnd == GetDesktopWindow())
89 EnumWindows(uia_win_event_enum_top_level_hwnds, (LPARAM)&event->u.clientside.win_event_hwnd_map);
90
91 return uia_hwnd_map_add_hwnd(&event->u.clientside.win_event_hwnd_map, hwnd);
92}
LONG_PTR LPARAM
Definition: minwindef.h:175
static BOOL CALLBACK uia_win_event_enum_top_level_hwnds(HWND hwnd, LPARAM lparam)
Definition: uia_event.c:68
HRESULT uia_hwnd_map_add_hwnd(struct rb_tree *hwnd_map, HWND hwnd)
Definition: uia_utils.c:442
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)

Referenced by uia_provider_attach_event().

◆ uia_event_AddRef()

static ULONG WINAPI uia_event_AddRef ( IWineUiaEvent *  iface)
static

Definition at line 1027 of file uia_event.c.

1028{
1029 struct uia_event *event = impl_from_IWineUiaEvent(iface);
1031
1032 TRACE("%p, refcount %ld\n", event, ref);
1033 return ref;
1034}
Definition: send.c:48
uint32_t ULONG
Definition: typedefs.h:59
static struct uia_event * impl_from_IWineUiaEvent(IWineUiaEvent *iface)
Definition: uia_event.c:1010

◆ uia_event_advise()

static HRESULT uia_event_advise ( struct uia_event event,
BOOL  advise_added,
LONG  start_idx 
)
static

Definition at line 1553 of file uia_event.c.

1554{
1555 IWineUiaEvent *event_iface;
1556 HRESULT hr;
1557
1558 if (event->u.clientside.git_cookie)
1559 {
1560 hr = get_interface_in_git(&IID_IWineUiaEvent, event->u.clientside.git_cookie,
1561 (IUnknown **)&event_iface);
1562 if (FAILED(hr))
1563 return hr;
1564 }
1565 else
1566 {
1567 event_iface = &event->IWineUiaEvent_iface;
1568 IWineUiaEvent_AddRef(event_iface);
1569 }
1570
1571 hr = IWineUiaEvent_advise_events(event_iface, advise_added, start_idx);
1572 IWineUiaEvent_Release(event_iface);
1573
1574 return hr;
1575}
HRESULT get_interface_in_git(REFIID riid, DWORD git_cookie, IUnknown **ret_iface)
Definition: uia_utils.c:79

Referenced by uia_add_clientside_event(), uia_event_advise_node(), and UiaRemoveEvent().

◆ uia_event_advise_events()

static HRESULT WINAPI uia_event_advise_events ( IWineUiaEvent *  iface,
BOOL  advise_added,
LONG  adviser_start_idx 
)
static

Definition at line 1076 of file uia_event.c.

1077{
1078 struct uia_event *event = impl_from_IWineUiaEvent(iface);
1079 HRESULT hr;
1080 int i;
1081
1082 TRACE("%p, %d, %ld\n", event, advise_added, adviser_start_idx);
1083
1084 for (i = adviser_start_idx; i < event->event_advisers_count; i++)
1085 {
1086 hr = IWineUiaEventAdviser_advise(event->event_advisers[i], advise_added, (UINT_PTR)event);
1087 if (FAILED(hr))
1088 return hr;
1089 }
1090
1091 /*
1092 * First call to advise events on a serverside provider, add it to the
1093 * events list so it can be raised.
1094 */
1095 if (!adviser_start_idx && advise_added && event->event_type == EVENT_TYPE_SERVERSIDE)
1096 {
1098 if (FAILED(hr))
1099 WARN("Failed to add event to event map, hr %#lx\n", hr);
1100 }
1101
1102 /*
1103 * Once we've advised of removal, no need to keep the advisers around.
1104 * We can also release our reference to the event map.
1105 */
1106 if (!advise_added)
1107 {
1108 InterlockedIncrement(&event->event_defunct);
1109 uia_event_map_entry_release(event->event_map_entry);
1110 event->event_map_entry = NULL;
1111
1113 }
1114
1115 return S_OK;
1116}
#define WARN(fmt,...)
Definition: precomp.h:61
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
static void uia_event_map_entry_release(struct uia_event_map_entry *entry)
Definition: uia_event.c:212
static void uia_event_clear_advisers(struct uia_event *event)
Definition: uia_event.c:996

◆ uia_event_advise_node()

HRESULT uia_event_advise_node ( struct uia_event event,
HUIANODE  node 
)

Definition at line 1577 of file uia_event.c.

1578{
1579 int old_event_advisers_count = event->event_advisers_count;
1580 HRESULT hr;
1581
1583 if (FAILED(hr))
1584 return hr;
1585
1586 if (event->event_advisers_count != old_event_advisers_count)
1587 hr = uia_event_advise(event, TRUE, old_event_advisers_count);
1588
1589 return hr;
1590}

Referenced by uia_com_focus_handler_advise_node(), uia_com_win_event_callback(), and UiaEventAddWindow().

◆ uia_event_adviser_AddRef()

static ULONG WINAPI uia_event_adviser_AddRef ( IWineUiaEventAdviser *  iface)
static

Definition at line 1318 of file uia_event.c.

1319{
1320 struct uia_event_adviser *adv_events = impl_from_IWineUiaEventAdviser(iface);
1321 ULONG ref = InterlockedIncrement(&adv_events->ref);
1322
1323 TRACE("%p, refcount %ld\n", adv_events, ref);
1324 return ref;
1325}
static struct uia_event_adviser * impl_from_IWineUiaEventAdviser(IWineUiaEventAdviser *iface)
Definition: uia_event.c:1301

◆ uia_event_adviser_advise()

static HRESULT WINAPI uia_event_adviser_advise ( IWineUiaEventAdviser *  iface,
BOOL  advise_added,
LONG_PTR  huiaevent 
)
static

Definition at line 1347 of file uia_event.c.

1348{
1349 struct uia_event_adviser *adv_events = impl_from_IWineUiaEventAdviser(iface);
1350 struct uia_event *event_data = (struct uia_event *)huiaevent;
1351 IRawElementProviderAdviseEvents *advise_events;
1352 HRESULT hr;
1353
1354 TRACE("%p, %d, %#Ix\n", adv_events, advise_added, huiaevent);
1355
1356 if (adv_events->git_cookie)
1357 {
1358 hr = get_interface_in_git(&IID_IRawElementProviderAdviseEvents, adv_events->git_cookie,
1359 (IUnknown **)&advise_events);
1360 if (FAILED(hr))
1361 return hr;
1362 }
1363 else
1364 {
1365 advise_events = adv_events->advise_events;
1366 IRawElementProviderAdviseEvents_AddRef(advise_events);
1367 }
1368
1369 if (advise_added)
1370 hr = IRawElementProviderAdviseEvents_AdviseEventAdded(advise_events, event_data->event_id, NULL);
1371 else
1372 hr = IRawElementProviderAdviseEvents_AdviseEventRemoved(advise_events, event_data->event_id, NULL);
1373
1374 IRawElementProviderAdviseEvents_Release(advise_events);
1375 return hr;
1376}

◆ uia_event_adviser_QueryInterface()

static HRESULT WINAPI uia_event_adviser_QueryInterface ( IWineUiaEventAdviser *  iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 1306 of file uia_event.c.

1307{
1308 *ppv = NULL;
1309 if (IsEqualIID(riid, &IID_IWineUiaEventAdviser) || IsEqualIID(riid, &IID_IUnknown))
1310 *ppv = iface;
1311 else
1312 return E_NOINTERFACE;
1313
1314 IWineUiaEventAdviser_AddRef(iface);
1315 return S_OK;
1316}
const GUID IID_IUnknown
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define E_NOINTERFACE
Definition: winerror.h:3479

◆ uia_event_adviser_Release()

static ULONG WINAPI uia_event_adviser_Release ( IWineUiaEventAdviser *  iface)
static

Definition at line 1327 of file uia_event.c.

1328{
1329 struct uia_event_adviser *adv_events = impl_from_IWineUiaEventAdviser(iface);
1330 ULONG ref = InterlockedDecrement(&adv_events->ref);
1331
1332 TRACE("%p, refcount %ld\n", adv_events, ref);
1333 if (!ref)
1334 {
1335 if (adv_events->git_cookie)
1336 {
1338 WARN("Failed to revoke advise events interface from GIT\n");
1339 }
1340 IRawElementProviderAdviseEvents_Release(adv_events->advise_events);
1341 free(adv_events);
1342 }
1343
1344 return ref;
1345}
#define InterlockedDecrement
Definition: armddk.h:52
HRESULT unregister_interface_in_git(DWORD git_cookie)
Definition: uia_utils.c:63

◆ uia_event_args_release()

static void uia_event_args_release ( struct uia_event_args args)
static

◆ uia_event_check_node_within_event_scope()

HRESULT uia_event_check_node_within_event_scope ( struct uia_event event,
HUIANODE  node,
SAFEARRAY rt_id,
HUIANODE *  clientside_nav_node_out 
)

Definition at line 1814 of file uia_event.c.

1816{
1818 struct uia_node *node_data = impl_from_IWineUiaNode((IWineUiaNode *)node);
1819 BOOL in_scope = FALSE;
1820 HRESULT hr = S_FALSE;
1821
1822 if (clientside_nav_node_out)
1823 *clientside_nav_node_out = NULL;
1824
1825 if (event->event_type == EVENT_TYPE_SERVERSIDE)
1826 assert(clientside_nav_node_out);
1827
1828 /* Event is no longer valid. */
1829 if (InterlockedCompareExchange(&event->event_defunct, 0, 0) != 0)
1830 return S_FALSE;
1831
1832 /* Can't match an event that doesn't have a runtime ID, early out. */
1833 if (!event->runtime_id)
1834 return S_FALSE;
1835
1836 if (event->desktop_subtree_event)
1837 return S_OK;
1838
1839 if (rt_id && !uia_compare_safearrays(rt_id, event->runtime_id, UIAutomationType_IntArray))
1840 return (event->scope & TreeScope_Element) ? S_OK : S_FALSE;
1841
1843 return S_FALSE;
1844
1845 V_VT(&prop_cond.Value) = VT_I4 | VT_ARRAY;
1846 V_ARRAY(&prop_cond.Value) = event->runtime_id;
1847
1848 IWineUiaNode_AddRef(&node_data->IWineUiaNode_iface);
1849 while (1)
1850 {
1851 HUIANODE node2 = NULL;
1852
1853 /*
1854 * When trying to match serverside events through navigation, we
1855 * don't want any clientside providers added in the server process.
1856 * Once we encounter a provider with an HWND, we pass it off to the
1857 * client for any further navigation.
1858 */
1859 if (event->event_type == EVENT_TYPE_SERVERSIDE)
1860 {
1861 if (node_data->hwnd)
1862 {
1863 *clientside_nav_node_out = (HUIANODE)&node_data->IWineUiaNode_iface;
1864 IWineUiaNode_AddRef(&node_data->IWineUiaNode_iface);
1865 in_scope = TRUE;
1866 break;
1867 }
1868 set_refuse_hwnd_providers(node_data, TRUE);
1869 }
1870
1871 hr = navigate_uia_node(node_data, NavigateDirection_Parent, &node2);
1872 if (FAILED(hr) || !node2)
1873 break;
1874
1875 IWineUiaNode_Release(&node_data->IWineUiaNode_iface);
1876
1877 node_data = impl_from_IWineUiaNode((IWineUiaNode *)node2);
1878 hr = uia_condition_check(node2, (struct UiaCondition *)&prop_cond);
1879 if (FAILED(hr))
1880 break;
1881
1883 {
1884 in_scope = TRUE;
1885 break;
1886 }
1887
1888 if (!(event->scope & TreeScope_Descendants))
1889 break;
1890 }
1891 IWineUiaNode_Release(&node_data->IWineUiaNode_iface);
1892
1893 if (FAILED(hr))
1894 return hr;
1895
1896 return in_scope ? S_OK : S_FALSE;
1897}
#define FALSE
Definition: types.h:117
@ VT_ARRAY
Definition: compat.h:2341
@ VT_I4
Definition: compat.h:2298
#define assert(_expr)
Definition: assert.h:32
unsigned int BOOL
Definition: ntddk_ex.h:94
#define InterlockedCompareExchange
Definition: interlocked.h:119
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_VT(A)
Definition: oleauto.h:211
IWineUiaNode IWineUiaNode_iface
Definition: uia_private.h:65
HWND hwnd
Definition: uia_private.h:74
HRESULT uia_condition_check(HUIANODE node, struct UiaCondition *condition)
Definition: uia_client.c:3363
HRESULT navigate_uia_node(struct uia_node *node, int nav_dir, HUIANODE *out_node)
Definition: uia_client.c:914
BOOL uia_condition_matched(HRESULT hr)
Definition: uia_client.c:3302
static void set_refuse_hwnd_providers(struct uia_node *node, BOOL refuse_hwnd_providers)
Definition: uia_event.c:1801
static struct uia_node * impl_from_IWineUiaNode(IWineUiaNode *iface)
Definition: uia_private.h:87
int uia_compare_safearrays(SAFEARRAY *sa1, SAFEARRAY *sa2, int prop_type)
Definition: uia_utils.c:334
@ TreeScope_Descendants
@ TreeScope_Children
@ TreeScope_Element
@ NavigateDirection_Parent
@ ConditionType_Property

Referenced by uia_com_win_event_callback(), uia_event_invoke(), and uia_raise_elprov_event_callback().

◆ uia_event_clear_advisers()

static void uia_event_clear_advisers ( struct uia_event event)
static

Definition at line 996 of file uia_event.c.

997{
998 int i;
999
1000 for (i = 0; i < event->event_advisers_count; i++)
1001 IWineUiaEventAdviser_Release(event->event_advisers[i]);
1002 free(event->event_advisers);
1003 event->event_advisers = NULL;
1004 event->event_advisers_count = event->event_advisers_arr_size = 0;
1005}

Referenced by uia_event_advise_events(), and uia_event_Release().

◆ uia_event_for_each()

HRESULT uia_event_for_each ( int  event_id,
UiaWineEventForEachCallback callback,
void user_data,
BOOL  clientside_only 
)

Definition at line 255 of file uia_event.c.

257{
258 struct uia_event_map_entry *event_entry;
259 HRESULT hr = S_OK;
260 int i;
261
263 if ((event_entry = uia_get_event_map_entry_for_event(event_id)))
264 InterlockedIncrement(&event_entry->refs);
266
267 if (!event_entry)
268 return S_OK;
269
270 for (i = 0; i < 2; i++)
271 {
272 struct list *events = !i ? &event_entry->events_list : &event_entry->serverside_events_list;
273 struct list *cursor, *cursor2;
274
275 if (i && clientside_only)
276 break;
277
279 {
280 struct uia_event *event = LIST_ENTRY(cursor, struct uia_event, event_list_entry);
281
282 /* Event is no longer valid. */
283 if (InterlockedCompareExchange(&event->event_defunct, 0, 0) != 0)
284 continue;
285
287 if (FAILED(hr))
288 goto exit;
289 }
290 }
291
292exit:
293 if (FAILED(hr))
294 WARN("Event callback failed with hr %#lx\n", hr);
295 uia_event_map_entry_release(event_entry);
296 return hr;
297}
Definition: list.h:37
static void * user_data
Definition: metahost.c:106
const char cursor[]
Definition: icontest.c:13
HANDLE events[2]
Definition: event.c:4
static IPrintDialogCallback callback
Definition: printdlg.c:326
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list)
Definition: list.h:192
Definition: uia_event.c:108
struct list serverside_events_list
Definition: uia_event.c:123
LONG refs
Definition: uia_event.c:110
int event_id
Definition: uia_event.c:112
struct list events_list
Definition: uia_event.c:122
struct list event_list_entry
Definition: uia_private.h:134
#define LIST_ENTRY(type)
Definition: queue.h:175
static struct uia_event_map_entry * uia_get_event_map_entry_for_event(int event_id)
Definition: uia_event.c:159

Referenced by uia_com_focus_win_event_handler(), uia_com_focus_win_event_msaa_handler(), uia_event_thread_process_queue(), and uia_raise_elprov_event().

◆ uia_event_invoke()

HRESULT uia_event_invoke ( HUIANODE  node,
HUIANODE  nav_start_node,
struct uia_event_args args,
struct uia_event event 
)

Definition at line 1738 of file uia_event.c.

1739{
1740 HRESULT hr = S_OK;
1741
1742 if (event->event_type == EVENT_TYPE_CLIENTSIDE)
1743 {
1744 SAFEARRAY *out_req;
1745 BSTR tree_struct;
1746
1747 if (nav_start_node && (hr = uia_event_check_node_within_event_scope(event, nav_start_node, NULL, NULL)) != S_OK)
1748 return hr;
1749
1750 hr = UiaGetUpdatedCache(node, &event->u.clientside.cache_req, NormalizeState_View, NULL, &out_req,
1751 &tree_struct);
1752 if (SUCCEEDED(hr))
1753 {
1754 hr = event->u.clientside.event_callback(event, args, out_req, tree_struct);
1755 if (FAILED(hr))
1756 WARN("Event callback failed with hr %#lx\n", hr);
1757 SafeArrayDestroy(out_req);
1758 SysFreeString(tree_struct);
1759 }
1760 }
1761 else
1762 {
1764 HUIANODE node2, nav_start_node2;
1765
1766 if (!(queue_event = calloc(1, sizeof(*queue_event))))
1767 return E_OUTOFMEMORY;
1768
1769 node2 = nav_start_node2 = NULL;
1770 hr = clone_uia_node(node, &node2);
1771 if (FAILED(hr))
1772 {
1774 return hr;
1775 }
1776
1777 if (nav_start_node)
1778 {
1779 hr = clone_uia_node(nav_start_node, &nav_start_node2);
1780 if (FAILED(hr))
1781 {
1783 UiaNodeRelease(node2);
1784 return hr;
1785 }
1786 }
1787
1788 queue_event->args = args;
1789 queue_event->event = event;
1790 queue_event->u.serverside.node = node2;
1791 queue_event->u.serverside.nav_start_node = nav_start_node2;
1792
1794 IWineUiaEvent_AddRef(&event->IWineUiaEvent_iface);
1796 }
1797
1798 return hr;
1799}
void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD time, DWORD seq)
Definition: device.c:1025
OLECHAR * BSTR
Definition: compat.h:2293
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
HUIANODE nav_start_node
Definition: uia_event.c:528
HRESULT WINAPI UiaGetUpdatedCache(HUIANODE huianode, struct UiaCacheRequest *cache_req, enum NormalizeState normalize_state, struct UiaCondition *normalize_cond, SAFEARRAY **out_req, BSTR *tree_struct)
Definition: uia_client.c:3450
BOOL WINAPI UiaNodeRelease(HUIANODE huianode)
Definition: uia_client.c:2876
HRESULT clone_uia_node(HUIANODE in_node, HUIANODE *out_node)
Definition: uia_client.c:738
static void uia_event_queue_push(struct uia_queue_event *event, int queue_event_type)
Definition: uia_event.c:550
HRESULT uia_event_check_node_within_event_scope(struct uia_event *event, HUIANODE node, SAFEARRAY *rt_id, HUIANODE *clientside_nav_node_out)
Definition: uia_event.c:1814
@ NormalizeState_View

Referenced by uia_com_focus_win_event_msaa_callback(), uia_raise_clientside_event(), and uia_raise_elprov_event_callback().

◆ uia_event_map_add_event()

static HRESULT uia_event_map_add_event ( struct uia_event event)
static

Definition at line 170 of file uia_event.c.

171{
172 const int subtree_scope = TreeScope_Element | TreeScope_Descendants;
173 struct uia_event_map_entry *event_entry;
174
175 if (((event->scope & subtree_scope) == subtree_scope) && event->runtime_id &&
176 !uia_compare_safearrays(uia_get_desktop_rt_id(), event->runtime_id, UIAutomationType_IntArray))
177 event->desktop_subtree_event = TRUE;
178
180
181 if (!(event_entry = uia_get_event_map_entry_for_event(event->event_id)))
182 {
183 if (!(event_entry = calloc(1, sizeof(*event_entry))))
184 {
186 return E_OUTOFMEMORY;
187 }
188
189 event_entry->event_id = event->event_id;
190 list_init(&event_entry->events_list);
191 list_init(&event_entry->serverside_events_list);
192
195 rb_put(&uia_event_map.event_map, &event->event_id, &event_entry->entry);
197 }
198
199 IWineUiaEvent_AddRef(&event->IWineUiaEvent_iface);
200 if (event->event_type == EVENT_TYPE_SERVERSIDE)
201 list_add_head(&event_entry->serverside_events_list, &event->event_list_entry);
202 else
203 list_add_head(&event_entry->events_list, &event->event_list_entry);
204 InterlockedIncrement(&event_entry->refs);
205
206 event->event_map_entry = event_entry;
208
209 return S_OK;
210}
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
struct rb_entry entry
Definition: uia_event.c:109
LONG event_count
Definition: uia_event.c:100
struct rb_tree event_map
Definition: uia_event.c:99
static int uia_event_map_id_compare(const void *key, const struct rb_entry *entry)
Definition: uia_event.c:151
static SAFEARRAY * uia_get_desktop_rt_id(void)
Definition: uia_event.c:42

Referenced by uia_add_clientside_event(), and uia_event_advise_events().

◆ uia_event_map_entry_release()

static void uia_event_map_entry_release ( struct uia_event_map_entry entry)
static

Definition at line 212 of file uia_event.c.

213{
215
216 if (!ref)
217 {
218 struct list *cursor, *cursor2;
219
221
222 /*
223 * Someone grabbed this while we were waiting to enter the CS, abort
224 * destruction.
225 */
226 if (InterlockedCompareExchange(&entry->refs, 0, 0) != 0)
227 {
229 return;
230 }
231
235
236 /* Release all events in the list. */
237 LIST_FOR_EACH_SAFE(cursor, cursor2, &entry->events_list)
238 {
239 struct uia_event *event = LIST_ENTRY(cursor, struct uia_event, event_list_entry);
240
241 IWineUiaEvent_Release(&event->IWineUiaEvent_iface);
242 }
243
244 LIST_FOR_EACH_SAFE(cursor, cursor2, &entry->serverside_events_list)
245 {
246 struct uia_event *event = LIST_ENTRY(cursor, struct uia_event, event_list_entry);
247
248 IWineUiaEvent_Release(&event->IWineUiaEvent_iface);
249 }
250
251 free(entry);
252 }
253}
uint32_t entry
Definition: isohybrid.c:63
static void rb_remove(struct rb_tree *tree, struct rb_entry *entry)
Definition: rbtree.h:272

Referenced by uia_event_advise_events(), and uia_event_for_each().

◆ uia_event_map_id_compare()

static int uia_event_map_id_compare ( const void key,
const struct rb_entry entry 
)
static

Definition at line 151 of file uia_event.c.

152{
153 struct uia_event_map_entry *event_entry = RB_ENTRY_VALUE(entry, struct uia_event_map_entry, entry);
154 int event_id = *((int *)key);
155
156 return (event_entry->event_id > event_id) - (event_entry->event_id < event_id);
157}
Definition: copy.c:22

Referenced by uia_event_map_add_event().

◆ uia_event_QueryInterface()

static HRESULT WINAPI uia_event_QueryInterface ( IWineUiaEvent *  iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 1015 of file uia_event.c.

1016{
1017 *ppv = NULL;
1018 if (IsEqualIID(riid, &IID_IWineUiaEvent) || IsEqualIID(riid, &IID_IUnknown))
1019 *ppv = iface;
1020 else
1021 return E_NOINTERFACE;
1022
1023 IWineUiaEvent_AddRef(iface);
1024 return S_OK;
1025}

◆ uia_event_queue_pop()

static struct uia_queue_event * uia_event_queue_pop ( struct list event_queue)
static

Definition at line 574 of file uia_event.c.

575{
577
579
580 if (!list_empty(event_queue))
581 {
583 list_remove(list_head(event_queue));
584 }
585
587 return queue_event;
588}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
Definition: list.h:15
struct list event_queue_entry
Definition: uia_event.c:515
static CRITICAL_SECTION event_thread_cs
Definition: uia_event.c:498

Referenced by uia_event_thread_process_queue().

◆ uia_event_queue_push()

static void uia_event_queue_push ( struct uia_queue_event event,
int  queue_event_type 
)
static

Definition at line 550 of file uia_event.c.

551{
552 event->queue_event_type = queue_event_type;
554
555 if (queue_event_type == QUEUE_EVENT_TYPE_WIN_EVENT)
556 {
557 struct uia_queue_win_event *win_event = (struct uia_queue_win_event *)event;
558
559 if (win_event->hook != event_thread.hook)
560 {
561 free(event);
562 goto exit;
563 }
564 }
565
566 assert(event_thread.event_queue);
567 list_add_tail(event_thread.event_queue, &event->event_queue_entry);
569
570exit:
572}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
HWINEVENTHOOK hook
Definition: uia_event.c:541
#define WM_UIA_EVENT_THREAD_PROCESS_QUEUE
Definition: uia_event.c:496
static struct uia_event_thread event_thread
Definition: uia_event.c:497
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)

Referenced by uia_event_invoke(), uia_event_raise_event(), and uia_event_thread_win_event_proc().

◆ uia_event_raise_event()

static HRESULT WINAPI uia_event_raise_event ( IWineUiaEvent *  iface,
VARIANT  in_node,
VARIANT  in_nav_start_node 
)
static

Definition at line 1146 of file uia_event.c.

1147{
1148 struct uia_event *event = impl_from_IWineUiaEvent(iface);
1150 struct uia_event_args *args;
1151
1152 TRACE("%p, %s, %s\n", iface, debugstr_variant(&in_node), debugstr_variant(&in_nav_start_node));
1153
1154 assert(event->event_type != EVENT_TYPE_SERVERSIDE);
1155
1156 if (!(queue_event = calloc(1, sizeof(*queue_event))))
1157 return E_OUTOFMEMORY;
1158
1160 {
1162 return E_OUTOFMEMORY;
1163 }
1164
1165 queue_event->args = args;
1166 queue_event->event = event;
1167 queue_event->u.clientside.node = V_I4(&in_node);
1168 if (V_VT(&in_nav_start_node) == VT_I4)
1169 queue_event->u.clientside.nav_start_node = V_I4(&in_nav_start_node);
1170
1171 IWineUiaEvent_AddRef(&event->IWineUiaEvent_iface);
1173
1174 return S_OK;
1175}
static const char * debugstr_variant(const VARIANT *var)
Definition: dom.c:505
#define V_I4(A)
Definition: oleauto.h:247
static struct uia_event_args * create_uia_event_args(const struct uia_event_info *event_info)
Definition: uia_event.c:305
const struct uia_event_info * uia_event_info_from_id(EVENTID event_id)
Definition: uia_ids.c:438

◆ uia_event_Release()

static ULONG WINAPI uia_event_Release ( IWineUiaEvent *  iface)
static

Definition at line 1036 of file uia_event.c.

1037{
1038 struct uia_event *event = impl_from_IWineUiaEvent(iface);
1040
1041 TRACE("%p, refcount %ld\n", event, ref);
1042 if (!ref)
1043 {
1044 /*
1045 * If this event has an event_map_entry, it should've been released
1046 * before hitting a reference count of 0.
1047 */
1048 assert(!event->event_map_entry);
1049
1050 SafeArrayDestroy(event->runtime_id);
1051 if (event->event_type == EVENT_TYPE_CLIENTSIDE)
1052 {
1053 uia_cache_request_destroy(&event->u.clientside.cache_req);
1054 if (event->u.clientside.event_thread_started)
1056 uia_hwnd_map_destroy(&event->u.clientside.win_event_hwnd_map);
1057 }
1058 else
1059 {
1061 rb_remove(&uia_event_map.serverside_event_map, &event->u.serverside.serverside_event_entry);
1064 if (event->u.serverside.event_iface)
1065 IWineUiaEvent_Release(event->u.serverside.event_iface);
1067 }
1068
1070 free(event);
1071 }
1072
1073 return ref;
1074}
static void uia_stop_event_thread(void)
Definition: uia_event.c:976
void uia_hwnd_map_destroy(struct rb_tree *hwnd_map)
Definition: uia_utils.c:484
void uia_cache_request_destroy(struct UiaCacheRequest *cache_req)
Definition: uia_utils.c:257

◆ uia_event_set_event_data()

static HRESULT WINAPI uia_event_set_event_data ( IWineUiaEvent *  iface,
const GUID event_guid,
LONG  scope,
VARIANT  runtime_id,
IWineUiaEvent *  event_iface 
)
static

Definition at line 1118 of file uia_event.c.

1120{
1121 struct uia_event *event = impl_from_IWineUiaEvent(iface);
1122
1123 TRACE("%p, %s, %ld, %s, %p\n", event, debugstr_guid(event_guid), scope, debugstr_variant(&runtime_id), event_iface);
1124
1125 assert(event->event_type == EVENT_TYPE_SERVERSIDE);
1126
1127 event->event_id = UiaLookupId(AutomationIdentifierType_Event, event_guid);
1128 event->scope = scope;
1129 if (V_VT(&runtime_id) == (VT_I4 | VT_ARRAY))
1130 {
1131 HRESULT hr;
1132
1133 hr = SafeArrayCopy(V_ARRAY(&runtime_id), &event->runtime_id);
1134 if (FAILED(hr))
1135 {
1136 WARN("Failed to copy runtime id, hr %#lx\n", hr);
1137 return hr;
1138 }
1139 }
1140 event->u.serverside.event_iface = event_iface;
1141 IWineUiaEvent_AddRef(event_iface);
1142
1143 return S_OK;
1144}
#define debugstr_guid
Definition: kernel32.h:35
IWineUiaEvent * event_iface
Definition: uia_private.h:152
int WINAPI UiaLookupId(enum AutomationIdentifierType type, const GUID *guid)
Definition: uia_ids.c:627
@ AutomationIdentifierType_Event

◆ uia_event_sink_list_add_event()

static HRESULT uia_event_sink_list_add_event ( struct list sink_events,
IRawElementProviderSimple *  elprov,
struct uia_event_args args 
)
static

Definition at line 333 of file uia_event.c.

335{
336 struct event_sink_event *sink_event = calloc(1, sizeof(*sink_event));
337
338 if (!sink_event)
339 return E_OUTOFMEMORY;
340
341 IRawElementProviderSimple_AddRef(elprov);
343
344 sink_event->elprov = elprov;
345 sink_event->args = args;
346 list_add_tail(sink_events, &sink_event->event_sink_list_entry);
347
348 return S_OK;
349}
struct uia_event_args * args
Definition: uia_event.c:330
struct list event_sink_list_entry
Definition: uia_event.c:327
IRawElementProviderSimple * elprov
Definition: uia_event.c:329

Referenced by uia_proxy_win_event_sink_AddAutomationEvent().

◆ uia_event_thread_proc()

static DWORD WINAPI uia_event_thread_proc ( void arg)
static

Definition at line 884 of file uia_event.c.

885{
886 HANDLE initialized_event = arg;
887 struct list event_queue;
889 HWND hwnd;
890 MSG msg;
891
892 list_init(&event_queue);
894 hwnd = CreateWindowW(L"Message", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
895 if (!hwnd)
896 {
897 WARN("CreateWindow failed: %ld\n", GetLastError());
900 }
901
902 event_thread.hwnd = hwnd;
903 event_thread.event_queue = &event_queue;
904 event_thread.hook = hook = SetWinEventHook(EVENT_MIN, EVENT_MAX, 0, uia_event_thread_win_event_proc, 0, 0,
906
907 /* Initialization complete, thread can now process window messages. */
908 SetEvent(initialized_event);
909 TRACE("Event thread started.\n");
910 while (GetMessageW(&msg, NULL, 0, 0))
911 {
912 if ((msg.hwnd == hwnd) && ((msg.message == WM_UIA_EVENT_THREAD_STOP) ||
914 {
915 uia_event_thread_process_queue(&event_queue);
916 if (msg.message == WM_UIA_EVENT_THREAD_STOP)
917 break;
918 }
919
922 }
923
924 TRACE("Shutting down UI Automation event thread.\n");
925
930}
@ hook
Definition: SystemMenu.c:35
#define msg(x)
Definition: auth_time.c:54
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(void *reserved, DWORD model)
Definition: combase.c:2803
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode)
Definition: loader.c:507
#define L(x)
Definition: resources.c:13
static HWINEVENTHOOK(WINAPI *pSetWinEventHook)(DWORD
@ COINIT_MULTITHREADED
Definition: objbase.h:280
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
#define WM_UIA_EVENT_THREAD_STOP
Definition: uia_event.c:495
static void CALLBACK uia_event_thread_win_event_proc(HWINEVENTHOOK hook, DWORD event_id, HWND hwnd, LONG obj_id, LONG child_id, DWORD thread_id, DWORD event_time)
Definition: uia_event.c:858
static void uia_event_thread_process_queue(struct list *event_queue)
Definition: uia_event.c:806
HMODULE huia_module
Definition: uia_main.c:29
HWINEVENTHOOK WINAPI SetWinEventHook(UINT, UINT, HMODULE, WINEVENTPROC, DWORD, DWORD, UINT)
Definition: hook.c:344
BOOL WINAPI UnhookWinEvent(HWINEVENTHOOK)
#define WINEVENT_OUTOFCONTEXT
Definition: winable.h:32
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void * arg
Definition: msvc.h:10
#define HWND_MESSAGE
Definition: winuser.h:1221
BOOL WINAPI TranslateMessage(_In_ const MSG *)
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4470
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
BOOL WINAPI DestroyWindow(_In_ HWND)

Referenced by uia_start_event_thread().

◆ uia_event_thread_process_queue()

static void uia_event_thread_process_queue ( struct list event_queue)
static

Definition at line 806 of file uia_event.c.

807{
808 while (1)
809 {
810 struct uia_queue_event *event;
811 HRESULT hr = S_OK;
812
813 if (!(event = uia_event_queue_pop(event_queue)))
814 break;
815
816 switch (event->queue_event_type)
817 {
820 {
822
823 if (event->queue_event_type == QUEUE_EVENT_TYPE_SERVERSIDE)
825 else
827
829 IWineUiaEvent_Release(&uia_event->event->IWineUiaEvent_iface);
830 break;
831 }
832
834 {
835 struct uia_queue_win_event *win_event = (struct uia_queue_win_event *)event;
836
837 hr = uia_com_win_event_callback(win_event->event_id, win_event->hwnd, win_event->obj_id, win_event->child_id,
838 win_event->thread_id, win_event->event_time);
839 if (FAILED(hr))
840 WARN("uia_com_win_event_callback failed with hr %#lx\n", hr);
841
843 (void *)win_event, TRUE);
844 break;
845 }
846
847 default:
848 break;
849 }
850
851 if (FAILED(hr))
852 WARN("Failed to raise event type %d with hr %#lx\n", event->queue_event_type, hr);
853
854 free(event);
855 }
856}
IWineUiaEvent IWineUiaEvent_iface
Definition: uia_private.h:122
HRESULT uia_com_win_event_callback(DWORD event_id, HWND hwnd, LONG obj_id, LONG child_id, DWORD thread_id, DWORD event_time)
static void uia_event_args_release(struct uia_event_args *args)
Definition: uia_event.c:319
static HRESULT uia_raise_clientside_event(struct uia_queue_uia_event *event)
Definition: uia_event.c:590
static HRESULT uia_win_event_for_each_callback(struct uia_event *event, void *data)
Definition: uia_event.c:733
static struct uia_queue_event * uia_event_queue_pop(struct list *event_queue)
Definition: uia_event.c:574
static int win_event_to_uia_event_id(int win_event)
Definition: uia_event.c:52
static HRESULT uia_raise_serverside_event(struct uia_queue_uia_event *event)
Definition: uia_event.c:622
HRESULT uia_event_for_each(int event_id, UiaWineEventForEachCallback *callback, void *user_data, BOOL clientside_only)
Definition: uia_event.c:255

Referenced by uia_event_thread_proc().

◆ uia_event_thread_win_event_proc()

static void CALLBACK uia_event_thread_win_event_proc ( HWINEVENTHOOK  hook,
DWORD  event_id,
HWND  hwnd,
LONG  obj_id,
LONG  child_id,
DWORD  thread_id,
DWORD  event_time 
)
static

Definition at line 858 of file uia_event.c.

860{
861 struct uia_queue_win_event *win_event;
862
863 TRACE("%p, %ld, %p, %ld, %ld, %ld, %ld\n", hook, event_id, hwnd, obj_id, child_id, thread_id, event_time);
864
866 return;
867
868 if (!(win_event = calloc(1, sizeof(*win_event))))
869 {
870 ERR("Failed to allocate uia_queue_win_event structure\n");
871 return;
872 }
873
874 win_event->hook = hook;
875 win_event->event_id = event_id;
876 win_event->hwnd = hwnd;
877 win_event->obj_id = obj_id;
878 win_event->child_id = child_id;
879 win_event->thread_id = thread_id;
880 win_event->event_time = event_time;
882}
static DWORD thread_id
Definition: protocol.c:159
struct uia_queue_event queue_entry
Definition: uia_event.c:539

Referenced by uia_event_thread_proc().

◆ uia_get_desktop_rt_id()

static SAFEARRAY * uia_get_desktop_rt_id ( void  )
static

Definition at line 42 of file uia_event.c.

43{
44 static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
45
48
50}
BOOL WINAPI InitOnceExecuteOnce(_Inout_ PINIT_ONCE InitOnce, _In_ __callback PINIT_ONCE_FN InitFn, _Inout_opt_ PVOID Parameter, _Outptr_opt_result_maybenull_ LPVOID *Context)
Definition: InitOnce.c:12
static SAFEARRAY * uia_desktop_node_rt_id
Definition: uia_event.c:26
static BOOL WINAPI uia_init_desktop_rt_id(INIT_ONCE *once, void *param, void **ctx)
Definition: uia_event.c:27
RTL_RUN_ONCE INIT_ONCE
Definition: winbase.h:3680
#define INIT_ONCE_STATIC_INIT
Definition: winbase.h:591

Referenced by uia_event_map_add_event().

◆ uia_get_event_map_entry_for_event()

static struct uia_event_map_entry * uia_get_event_map_entry_for_event ( int  event_id)
static

Definition at line 159 of file uia_event.c.

160{
161 struct uia_event_map_entry *map_entry = NULL;
162 struct rb_entry *rb_entry;
163
165 map_entry = RB_ENTRY_VALUE(rb_entry, struct uia_event_map_entry, entry);
166
167 return map_entry;
168}

Referenced by uia_event_for_each(), and uia_event_map_add_event().

◆ uia_init_desktop_rt_id()

static BOOL WINAPI uia_init_desktop_rt_id ( INIT_ONCE once,
void param,
void **  ctx 
)
static

Definition at line 27 of file uia_event.c.

28{
30
31 if ((sa = SafeArrayCreateVector(VT_I4, 0, 2)))
32 {
35 else
37 }
38
40}
SAFEARRAY *WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
Definition: safearray.c:677
HRESULT write_runtime_id_base(SAFEARRAY *sa, HWND hwnd)
Definition: uia_utils.c:102

Referenced by uia_get_desktop_rt_id().

◆ uia_proxy_win_event_sink_AddAutomationEvent()

static HRESULT WINAPI uia_proxy_win_event_sink_AddAutomationEvent ( IProxyProviderWinEventSink *  iface,
IRawElementProviderSimple *  elprov,
EVENTID  event_id 
)
static

Definition at line 419 of file uia_event.c.

421{
423 struct uia_event_args *args;
424 HRESULT hr = S_OK;
425
426 TRACE("%p, %p, %d\n", iface, elprov, event_id);
427
428 if (event_id != sink->event_id)
429 return S_OK;
430
432 if (!args)
433 return E_OUTOFMEMORY;
434
435 if (InterlockedCompareExchange(&sink->sink_defunct, 0, 0) == 0)
436 hr = uia_event_sink_list_add_event(&sink->sink_events, elprov, args);
438 return hr;
439}
static HRESULT uia_event_sink_list_add_event(struct list *sink_events, IRawElementProviderSimple *elprov, struct uia_event_args *args)
Definition: uia_event.c:333
static struct uia_proxy_win_event_sink * impl_from_IProxyProviderWinEventSink(IProxyProviderWinEventSink *iface)
Definition: uia_event.c:364

◆ uia_proxy_win_event_sink_AddAutomationPropertyChangedEvent()

static HRESULT WINAPI uia_proxy_win_event_sink_AddAutomationPropertyChangedEvent ( IProxyProviderWinEventSink *  iface,
IRawElementProviderSimple *  elprov,
PROPERTYID  prop_id,
VARIANT  new_value 
)
static

Definition at line 412 of file uia_event.c.

414{
415 FIXME("%p, %p, %d, %s: stub\n", iface, elprov, prop_id, debugstr_variant(&new_value));
416 return E_NOTIMPL;
417}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ uia_proxy_win_event_sink_AddRef()

static ULONG WINAPI uia_proxy_win_event_sink_AddRef ( IProxyProviderWinEventSink *  iface)
static

Definition at line 385 of file uia_event.c.

386{
389
390 TRACE("%p, refcount %ld\n", sink, ref);
391
392 return ref;
393}

◆ uia_proxy_win_event_sink_AddStructureChangedEvent()

static HRESULT WINAPI uia_proxy_win_event_sink_AddStructureChangedEvent ( IProxyProviderWinEventSink *  iface,
IRawElementProviderSimple *  elprov,
enum StructureChangeType  structure_change_type,
SAFEARRAY runtime_id 
)
static

Definition at line 441 of file uia_event.c.

443{
444 FIXME("%p, %p, %d, %p: stub\n", iface, elprov, structure_change_type, runtime_id);
445 return E_NOTIMPL;
446}

◆ uia_proxy_win_event_sink_QueryInterface()

static HRESULT WINAPI uia_proxy_win_event_sink_QueryInterface ( IProxyProviderWinEventSink *  iface,
REFIID  riid,
void **  obj 
)
static

Definition at line 369 of file uia_event.c.

370{
372
373 *obj = NULL;
374 if (IsEqualIID(riid, &IID_IProxyProviderWinEventSink) || IsEqualIID(riid, &IID_IUnknown))
375 *obj = iface;
376 else if (IsEqualIID(riid, &IID_IMarshal))
377 return IUnknown_QueryInterface(sink->marshal, riid, obj);
378 else
379 return E_NOINTERFACE;
380
381 IProxyProviderWinEventSink_AddRef(iface);
382 return S_OK;
383}

◆ uia_proxy_win_event_sink_Release()

static ULONG WINAPI uia_proxy_win_event_sink_Release ( IProxyProviderWinEventSink *  iface)
static

Definition at line 395 of file uia_event.c.

396{
399
400 TRACE("%p, refcount %ld\n", sink, ref);
401
402 if (!ref)
403 {
404 assert(list_empty(&sink->sink_events));
405 IUnknown_Release(sink->marshal);
406 free(sink);
407 }
408
409 return ref;
410}

◆ uia_raise_clientside_event()

static HRESULT uia_raise_clientside_event ( struct uia_queue_uia_event event)
static

Definition at line 590 of file uia_event.c.

591{
592 HUIANODE node, nav_start_node;
593 HRESULT hr;
594
595 node = nav_start_node = NULL;
596 hr = uia_node_from_lresult(event->u.clientside.node, &node, 0);
597 if (FAILED(hr))
598 {
599 WARN("Failed to create node from lresult, hr %#lx\n", hr);
600 uia_node_lresult_release(event->u.clientside.nav_start_node);
601 return hr;
602 }
603
604 if (event->u.clientside.nav_start_node)
605 {
606 hr = uia_node_from_lresult(event->u.clientside.nav_start_node, &nav_start_node, 0);
607 if (FAILED(hr))
608 {
609 WARN("Failed to create nav_start_node from lresult, hr %#lx\n", hr);
611 return hr;
612 }
613 }
614
615 hr = uia_event_invoke(node, nav_start_node, event->args, event->event);
617 UiaNodeRelease(nav_start_node);
618
619 return hr;
620}
HRESULT uia_node_from_lresult(LRESULT lr, HUIANODE *huianode, int node_flags)
Definition: uia_client.c:2642
void uia_node_lresult_release(LRESULT lr)
Definition: uia_client.c:2683
HRESULT uia_event_invoke(HUIANODE node, HUIANODE nav_start_node, struct uia_event_args *args, struct uia_event *event)
Definition: uia_event.c:1738

Referenced by uia_event_thread_process_queue().

◆ uia_raise_elprov_event()

static HRESULT uia_raise_elprov_event ( IRawElementProviderSimple *  elprov,
struct uia_event_args args 
)
static

Definition at line 1928 of file uia_event.c.

1929{
1930 struct uia_elprov_event_data event_data = { elprov, args };
1931 enum ProviderOptions prov_opts = 0;
1932 HRESULT hr;
1933
1934 hr = IRawElementProviderSimple_get_ProviderOptions(elprov, &prov_opts);
1935 if (FAILED(hr))
1936 return hr;
1937
1938 event_data.clientside_only = !(prov_opts & ProviderOptions_ServerSideProvider);
1939 hr = uia_event_for_each(args->simple_args.EventId, uia_raise_elprov_event_callback, (void *)&event_data,
1940 event_data.clientside_only);
1941 if (FAILED(hr))
1942 WARN("uia_event_for_each failed with hr %#lx\n", hr);
1943
1944 UiaNodeRelease(event_data.node);
1945 SafeArrayDestroy(event_data.rt_id);
1946
1947 return hr;
1948}
IRawElementProviderSimple * elprov
Definition: uia_event.c:724
SAFEARRAY * rt_id
Definition: uia_event.c:728
static HRESULT uia_raise_elprov_event_callback(struct uia_event *event, void *data)
Definition: uia_event.c:1899
@ ProviderOptions_ServerSideProvider

Referenced by UiaRaiseAutomationEvent().

◆ uia_raise_elprov_event_callback()

static HRESULT uia_raise_elprov_event_callback ( struct uia_event event,
void data 
)
static

Definition at line 1899 of file uia_event.c.

1900{
1901 struct uia_elprov_event_data *event_data = (struct uia_elprov_event_data *)data;
1902 HUIANODE nav_node = NULL;
1903 HRESULT hr = S_OK;
1904
1905 if (!event_data->node)
1906 {
1907 /*
1908 * For events raised on server-side providers, we don't want to add any
1909 * clientside HWND providers.
1910 */
1911 hr = create_uia_node_from_elprov(event_data->elprov, &event_data->node, event_data->clientside_only, 0);
1912 if (FAILED(hr))
1913 return hr;
1914
1915 hr = UiaGetRuntimeId(event_data->node, &event_data->rt_id);
1916 if (FAILED(hr))
1917 return hr;
1918 }
1919
1920 hr = uia_event_check_node_within_event_scope(event, event_data->node, event_data->rt_id, &nav_node);
1921 if (hr == S_OK)
1922 hr = uia_event_invoke(event_data->node, nav_node, event_data->args, event);
1923
1924 UiaNodeRelease(nav_node);
1925 return hr;
1926}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
struct uia_event_args * args
Definition: uia_event.c:725
HRESULT WINAPI UiaGetRuntimeId(HUIANODE huianode, SAFEARRAY **runtime_id)
Definition: uia_client.c:3045
HRESULT create_uia_node_from_elprov(IRawElementProviderSimple *elprov, HUIANODE *out_node, BOOL get_hwnd_providers, int node_flags)
Definition: uia_client.c:2049

Referenced by uia_raise_elprov_event(), and uia_win_event_for_each_callback().

◆ uia_raise_serverside_event()

static HRESULT uia_raise_serverside_event ( struct uia_queue_uia_event event)
static

Definition at line 622 of file uia_event.c.

623{
624 HRESULT hr = S_OK;
625 LRESULT lr, lr2;
626 VARIANT v, v2;
627
628 /*
629 * uia_lresult_from_node is expected to release the node here upon
630 * failure.
631 */
632 lr = lr2 = 0;
633 if (!(lr = uia_lresult_from_node(event->u.serverside.node)))
634 {
635 UiaNodeRelease(event->u.serverside.nav_start_node);
636 return E_FAIL;
637 }
638
639 if (event->u.serverside.nav_start_node && !(lr2 = uia_lresult_from_node(event->u.serverside.nav_start_node)))
640 {
642 return E_FAIL;
643 }
644
645 VariantInit(&v2);
646 variant_init_i4(&v, lr);
647 if (lr2)
648 variant_init_i4(&v2, lr2);
649
650 hr = IWineUiaEvent_raise_event(event->event->u.serverside.event_iface, v, v2);
651 if (FAILED(hr))
652 {
655 }
656
657 return hr;
658}
const GLdouble * v
Definition: gl.h:2040
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
LONG_PTR LRESULT
Definition: minwindef.h:176
LRESULT uia_lresult_from_node(HUIANODE huianode)
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568

Referenced by uia_event_thread_process_queue().

◆ uia_serverside_event_adviser_AddRef()

static ULONG WINAPI uia_serverside_event_adviser_AddRef ( IWineUiaEventAdviser *  iface)
static

Definition at line 1457 of file uia_event.c.

1458{
1460 ULONG ref = InterlockedIncrement(&adv_events->ref);
1461
1462 TRACE("%p, refcount %ld\n", adv_events, ref);
1463 return ref;
1464}
static struct uia_serverside_event_adviser * impl_from_serverside_IWineUiaEventAdviser(IWineUiaEventAdviser *iface)
Definition: uia_event.c:1440

◆ uia_serverside_event_adviser_advise()

static HRESULT WINAPI uia_serverside_event_adviser_advise ( IWineUiaEventAdviser *  iface,
BOOL  advise_added,
LONG_PTR  huiaevent 
)
static

Definition at line 1480 of file uia_event.c.

1481{
1483 struct uia_event *event_data = (struct uia_event *)huiaevent;
1484 HRESULT hr;
1485
1486 TRACE("%p, %d, %#Ix\n", adv_events, advise_added, huiaevent);
1487
1488 if (advise_added)
1489 {
1490 const struct uia_event_info *event_info = uia_event_info_from_id(event_data->event_id);
1491 VARIANT v;
1492
1493 VariantInit(&v);
1494 if (event_data->runtime_id)
1495 {
1496 V_VT(&v) = VT_I4 | VT_ARRAY;
1497 V_ARRAY(&v) = event_data->runtime_id;
1498 }
1499
1500 hr = IWineUiaEvent_set_event_data(adv_events->event_iface, event_info->guid, event_data->scope, v,
1501 &event_data->IWineUiaEvent_iface);
1502 if (FAILED(hr))
1503 {
1504 WARN("Failed to set event data on serverside event, hr %#lx\n", hr);
1505 return hr;
1506 }
1507 }
1508
1509 return IWineUiaEvent_advise_events(adv_events->event_iface, advise_added, 0);
1510}

◆ uia_serverside_event_adviser_QueryInterface()

static HRESULT WINAPI uia_serverside_event_adviser_QueryInterface ( IWineUiaEventAdviser *  iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 1445 of file uia_event.c.

1446{
1447 *ppv = NULL;
1448 if (IsEqualIID(riid, &IID_IWineUiaEventAdviser) || IsEqualIID(riid, &IID_IUnknown))
1449 *ppv = iface;
1450 else
1451 return E_NOINTERFACE;
1452
1453 IWineUiaEventAdviser_AddRef(iface);
1454 return S_OK;
1455}

◆ uia_serverside_event_adviser_Release()

static ULONG WINAPI uia_serverside_event_adviser_Release ( IWineUiaEventAdviser *  iface)
static

Definition at line 1466 of file uia_event.c.

1467{
1469 ULONG ref = InterlockedDecrement(&adv_events->ref);
1470
1471 TRACE("%p, refcount %ld\n", adv_events, ref);
1472 if (!ref)
1473 {
1474 IWineUiaEvent_Release(adv_events->event_iface);
1475 free(adv_events);
1476 }
1477 return ref;
1478}

◆ uia_serverside_event_id_compare()

static int uia_serverside_event_id_compare ( const void key,
const struct rb_entry entry 
)
static

Definition at line 131 of file uia_event.c.

132{
133 struct uia_event *event = RB_ENTRY_VALUE(entry, struct uia_event, u.serverside.serverside_event_entry);
134 struct uia_event_identifier *event_id = (struct uia_event_identifier *)key;
135
136 if (event_id->proc_id != event->u.serverside.proc_id)
137 return (event_id->proc_id > event->u.serverside.proc_id) - (event_id->proc_id < event->u.serverside.proc_id);
138 else
139 return (event_id->event_cookie > event->event_cookie) - (event_id->event_cookie < event->event_cookie);
140}

Referenced by create_serverside_uia_event().

◆ uia_start_event_thread()

static BOOL uia_start_event_thread ( void  )
static

Definition at line 932 of file uia_event.c.

933{
934 BOOL started = TRUE;
935
937 if (++event_thread.ref == 1)
938 {
939 HANDLE ready_event = NULL;
940 HANDLE events[2];
942 DWORD wait_obj;
943
944 /* Increment DLL reference count. */
945 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
947
948 events[0] = ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
950 ready_event, 0, NULL)))
951 {
953 started = FALSE;
954 goto exit;
955 }
956
957 events[1] = event_thread.hthread;
959 if (wait_obj != WAIT_OBJECT_0)
960 {
961 CloseHandle(event_thread.hthread);
962 started = FALSE;
963 }
964
965exit:
966 if (ready_event)
967 CloseHandle(ready_event);
968 if (!started)
969 memset(&event_thread, 0, sizeof(event_thread));
970 }
971
973 return started;
974}
#define CloseHandle
Definition: compat.h:739
#define FreeLibrary(x)
Definition: compat.h:748
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:866
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
#define INFINITE
Definition: serial.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
static HMODULE hmodule
Definition: rasapi.c:29
#define memset(x, y, z)
Definition: compat.h:39
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:587
static DWORD WINAPI uia_event_thread_proc(void *arg)
Definition: uia_event.c:884
#define WAIT_OBJECT_0
Definition: winbase.h:383
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by create_serverside_uia_event(), uia_clientside_event_start_event_thread(), and uia_start_event_thread().

◆ uia_stop_event_thread()

static void uia_stop_event_thread ( void  )
static

Definition at line 976 of file uia_event.c.

Referenced by uia_event_Release().

◆ uia_win_event_enum_top_level_hwnds()

static BOOL CALLBACK uia_win_event_enum_top_level_hwnds ( HWND  hwnd,
LPARAM  lparam 
)
static

Definition at line 68 of file uia_event.c.

69{
70 struct rb_tree *hwnd_map = (struct rb_tree *)lparam;
71 HRESULT hr;
72
74 return TRUE;
75
76 hr = uia_hwnd_map_add_hwnd(hwnd_map, hwnd);
77 if (FAILED(hr))
78 WARN("Failed to add hwnd to map, hr %#lx\n", hr);
79
80 return TRUE;
81}
@ lparam
Definition: SystemMenu.c:31
Definition: rbtree.h:40
BOOL uia_hwnd_is_visible(HWND hwnd)
Definition: uia_utils.c:391

Referenced by uia_event_add_win_event_hwnd().

◆ uia_win_event_for_each_callback()

static HRESULT uia_win_event_for_each_callback ( struct uia_event event,
void data 
)
static

Definition at line 733 of file uia_event.c.

734{
735 struct uia_queue_win_event *win_event = (struct uia_queue_win_event *)data;
736 struct event_sink_event *sink_event, *sink_event2;
738 IRawElementProviderSimple *elprov;
739 struct uia_node *node_data;
740 HUIANODE node;
741 HRESULT hr;
742 int i;
743
744 /*
745 * Check if this HWND, or any of it's ancestors (excluding the desktop)
746 * are in our scope.
747 */
748 if (!uia_hwnd_map_check_hwnd(&event->u.clientside.win_event_hwnd_map, win_event->hwnd) &&
749 !uia_win_event_hwnd_map_contains_ancestors(&event->u.clientside.win_event_hwnd_map, win_event->hwnd))
750 return S_OK;
751
752 /* Has a native serverside provider, no need to do WinEvent translation. */
753 if (UiaHasServerSideProvider(win_event->hwnd))
754 return S_OK;
755
756 /*
757 * Regardless of the object ID of the WinEvent, OBJID_CLIENT is queried
758 * for the HWND with the same child ID as the WinEvent.
759 */
760 hr = create_msaa_provider_from_hwnd(win_event->hwnd, win_event->child_id, &elprov);
761 if (FAILED(hr))
762 return hr;
763
765 IRawElementProviderSimple_Release(elprov);
766 if (FAILED(hr))
767 return hr;
768
770 if (SUCCEEDED(hr))
771 {
772 node_data = impl_from_IWineUiaNode((IWineUiaNode *)node);
773 for (i = 0; i < node_data->prov_count; i++)
774 {
775 hr = respond_to_win_event_on_node_provider((IWineUiaNode *)node, i, win_event->event_id, win_event->hwnd, win_event->obj_id,
776 win_event->child_id, &sink->IProxyProviderWinEventSink_iface);
777 if (FAILED(hr) || !list_empty(&sink->sink_events))
778 break;
779 }
780
781 InterlockedIncrement(&sink->sink_defunct);
782 LIST_FOR_EACH_ENTRY_SAFE(sink_event, sink_event2, &sink->sink_events, struct event_sink_event, event_sink_list_entry)
783 {
784 struct uia_elprov_event_data event_data = { sink_event->elprov, sink_event->args, TRUE };
786
787 hr = uia_raise_elprov_event_callback(event, (void *)&event_data);
788 if (FAILED(hr))
789 WARN("uia_raise_elprov_event_callback failed with hr %#lx\n", hr);
790
791 UiaNodeRelease(event_data.node);
792 SafeArrayDestroy(event_data.rt_id);
793
794 IRawElementProviderSimple_Release(sink_event->elprov);
795 uia_event_args_release(sink_event->args);
796 free(sink_event);
797 }
798
799 IProxyProviderWinEventSink_Release(&sink->IProxyProviderWinEventSink_iface);
800 }
801
803 return hr;
804}
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
int prov_count
Definition: uia_private.h:70
HRESULT respond_to_win_event_on_node_provider(IWineUiaNode *node, int idx, DWORD win_event, HWND hwnd, LONG obj_id, LONG child_id, IProxyProviderWinEventSink *sink)
Definition: uia_client.c:381
BOOL WINAPI UiaHasServerSideProvider(HWND hwnd)
Definition: uia_client.c:2781
static BOOL uia_win_event_hwnd_map_contains_ancestors(struct rb_tree *hwnd_map, HWND hwnd)
Definition: uia_event.c:661
static HRESULT create_proxy_win_event_sink(struct uia_proxy_win_event_sink **out_sink, int event_id)
Definition: uia_event.c:457
HRESULT create_msaa_provider_from_hwnd(HWND hwnd, int in_child_id, IRawElementProviderSimple **ret_elprov)
Definition: uia_event.c:677
@ NODE_FLAG_IGNORE_COM_THREADING
Definition: uia_private.h:61
BOOL uia_hwnd_map_check_hwnd(struct rb_tree *hwnd_map, HWND hwnd)
Definition: uia_utils.c:437

Referenced by uia_event_thread_process_queue().

◆ uia_win_event_hwnd_map_contains_ancestors()

static BOOL uia_win_event_hwnd_map_contains_ancestors ( struct rb_tree hwnd_map,
HWND  hwnd 
)
static

Definition at line 661 of file uia_event.c.

662{
664 const HWND desktop = GetDesktopWindow();
665
666 while (parent && (parent != desktop))
667 {
668 if (uia_hwnd_map_check_hwnd(hwnd_map, parent))
669 return TRUE;
670
672 }
673
674 return FALSE;
675}
r parent
Definition: btrfs.c:3010
#define GA_PARENT
Definition: winuser.h:2892
HWND WINAPI GetAncestor(_In_ HWND, _In_ UINT)
Definition: window.c:929

Referenced by uia_win_event_for_each_callback().

◆ UiaAddEvent()

HRESULT WINAPI UiaAddEvent ( HUIANODE  huianode,
EVENTID  event_id,
UiaEventCallback callback,
enum TreeScope  scope,
PROPERTYID prop_ids,
int  prop_ids_count,
struct UiaCacheRequest cache_req,
HUIAEVENT *  huiaevent 
)

Definition at line 1675 of file uia_event.c.

1677{
1679 SAFEARRAY *sa;
1680 HRESULT hr;
1681
1682 TRACE("(%p, %d, %p, %#x, %p, %d, %p, %p)\n", huianode, event_id, callback, scope, prop_ids, prop_ids_count,
1683 cache_req, huiaevent);
1684
1685 if (!huianode || !callback || !cache_req || !huiaevent)
1686 return E_INVALIDARG;
1687
1688 if (!event_info)
1689 WARN("No event information for event ID %d\n", event_id);
1690
1691 *huiaevent = NULL;
1692 if (event_info && (event_info->event_arg_type == EventArgsType_PropertyChanged))
1693 {
1694 FIXME("Property changed event registration currently unimplemented\n");
1695 return E_NOTIMPL;
1696 }
1697
1698 hr = UiaGetRuntimeId(huianode, &sa);
1699 if (FAILED(hr))
1700 return hr;
1701
1702 hr = uia_add_clientside_event(huianode, event_id, scope, prop_ids, prop_ids_count, cache_req, sa,
1703 uia_clientside_event_callback, (void *)callback, huiaevent);
1705
1706 return hr;
1707}
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT uia_add_clientside_event(HUIANODE huianode, EVENTID event_id, enum TreeScope scope, PROPERTYID *prop_ids, int prop_ids_count, struct UiaCacheRequest *cache_req, SAFEARRAY *rt_id, UiaWineEventCallback *cback, void *cback_data, HUIAEVENT *huiaevent)
Definition: uia_event.c:1628
static HRESULT uia_clientside_event_callback(struct uia_event *event, struct uia_event_args *args, SAFEARRAY *cache_req, BSTR tree_struct)
Definition: uia_event.c:1618
@ EventArgsType_PropertyChanged

Referenced by test_uia_com_focus_change_event_handler_win_event_handling(), test_UiaAddEvent(), test_UiaAddEvent_args(), test_UiaAddEvent_client_proc(), and uia_proxy_provider_win_event_handler_test_thread().

◆ UiaEventAddWindow()

HRESULT WINAPI UiaEventAddWindow ( HUIAEVENT  huiaevent,
HWND  hwnd 
)

Definition at line 1595 of file uia_event.c.

1596{
1597 struct uia_event *event = unsafe_impl_from_IWineUiaEvent((IWineUiaEvent *)huiaevent);
1598 HUIANODE node;
1599 HRESULT hr;
1600
1601 TRACE("(%p, %p)\n", huiaevent, hwnd);
1602
1603 if (!event)
1604 return E_INVALIDARG;
1605
1606 assert(event->event_type == EVENT_TYPE_CLIENTSIDE);
1607
1609 if (FAILED(hr))
1610 return hr;
1611
1614
1615 return hr;
1616}
HRESULT WINAPI UiaNodeFromHandle(HWND hwnd, HUIANODE *huianode)
Definition: uia_client.c:2761
static struct uia_event * unsafe_impl_from_IWineUiaEvent(IWineUiaEvent *iface)
Definition: uia_event.c:1186
HRESULT uia_event_advise_node(struct uia_event *event, HUIANODE node)
Definition: uia_event.c:1577

Referenced by test_UiaAddEvent_client_proc(), and uia_proxy_provider_win_event_handler_test_thread().

◆ UiaRaiseAutomationEvent()

HRESULT WINAPI UiaRaiseAutomationEvent ( IRawElementProviderSimple *  elprov,
EVENTID  id 
)

Definition at line 1953 of file uia_event.c.

1954{
1956 struct uia_event_args *args;
1957 HRESULT hr;
1958
1959 TRACE("(%p, %d)\n", elprov, id);
1960
1961 if (!elprov)
1962 return E_INVALIDARG;
1963
1964 if (!event_info || event_info->event_arg_type != EventArgsType_Simple)
1965 {
1966 if (!event_info)
1967 FIXME("No event info structure for event id %d\n", id);
1968 else
1969 WARN("Wrong event raising function for event args type %d\n", event_info->event_arg_type);
1970
1971 return S_OK;
1972 }
1973
1975 if (!args)
1976 return E_OUTOFMEMORY;
1977
1978 hr = uia_raise_elprov_event(elprov, args);
1980 if (FAILED(hr))
1981 return hr;
1982
1983 return S_OK;
1984}
static HRESULT uia_raise_elprov_event(IRawElementProviderSimple *elprov, struct uia_event_args *args)
Definition: uia_event.c:1928
@ EventArgsType_Simple

Referenced by test_IUIAutomationEventHandler(), test_IUIAutomationFocusChangedEventHandler(), test_UiaAddEvent(), test_UiaRaiseAutomationEvent_args(), and uia_com_event_handler_test_thread().

◆ UiaRemoveEvent()

HRESULT WINAPI UiaRemoveEvent ( HUIAEVENT  huiaevent)

Definition at line 1712 of file uia_event.c.

1713{
1714 struct uia_event *event = unsafe_impl_from_IWineUiaEvent((IWineUiaEvent *)huiaevent);
1715 HRESULT hr;
1716
1717 TRACE("(%p)\n", event);
1718
1719 if (!event)
1720 return E_INVALIDARG;
1721
1722 assert(event->event_type == EVENT_TYPE_CLIENTSIDE);
1724 if (FAILED(hr))
1725 return hr;
1726
1727 if (event->u.clientside.git_cookie)
1728 {
1729 hr = unregister_interface_in_git(event->u.clientside.git_cookie);
1730 if (FAILED(hr))
1731 return hr;
1732 }
1733
1734 IWineUiaEvent_Release(&event->IWineUiaEvent_iface);
1735 return S_OK;
1736}

Referenced by test_uia_com_focus_change_event_handler_win_event_handling(), test_UiaAddEvent(), test_UiaAddEvent_args(), test_UiaAddEvent_client_proc(), test_UiaRemoveEvent_args(), uia_add_event_test_thread(), uia_event_handler_destroy(), and uia_proxy_provider_win_event_handler_test_thread().

◆ unsafe_impl_from_IWineUiaEvent()

static struct uia_event * unsafe_impl_from_IWineUiaEvent ( IWineUiaEvent *  iface)
static

Definition at line 1186 of file uia_event.c.

1187{
1188 if (!iface || (iface->lpVtbl != &uia_event_vtbl))
1189 return NULL;
1190
1191 return CONTAINING_RECORD(iface, struct uia_event, IWineUiaEvent_iface);
1192}

Referenced by UiaEventAddWindow(), and UiaRemoveEvent().

◆ win_event_to_uia_event_id()

static int win_event_to_uia_event_id ( int  win_event)
static

Definition at line 52 of file uia_event.c.

53{
54 switch (win_event)
55 {
56 case EVENT_OBJECT_FOCUS: return UIA_AutomationFocusChangedEventId;
57 case EVENT_SYSTEM_ALERT: return UIA_SystemAlertEventId;
58 case EVENT_OBJECT_SHOW: return UIA_StructureChangedEventId;
59 case EVENT_OBJECT_DESTROY: return UIA_StructureChangedEventId;
60
61 default:
62 break;
63 }
64
65 return 0;
66}

Referenced by uia_event_thread_process_queue(), and uia_event_thread_win_event_proc().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( uiautomation  )

Variable Documentation

◆ event_map_cs

◆ event_map_cs_debug

CRITICAL_SECTION_DEBUG event_map_cs_debug
static
Initial value:
=
{
0, 0, &event_map_cs,
0, 0, { (DWORD_PTR)(__FILE__ ": event_map_cs") }
}
#define DWORD_PTR
Definition: treelist.c:76
static CRITICAL_SECTION_DEBUG event_map_cs_debug
Definition: uia_event.c:143

Definition at line 143 of file uia_event.c.

◆ event_thread

◆ event_thread_cs

static CRITICAL_SECTION event_thread_cs = { &event_thread_cs_debug, -1, 0, 0, 0, 0 }
static

◆ event_thread_cs_debug

CRITICAL_SECTION_DEBUG event_thread_cs_debug
static
Initial value:
=
{
0, 0, { (DWORD_PTR)(__FILE__ ": event_thread_cs") }
}
static CRITICAL_SECTION_DEBUG event_thread_cs_debug
Definition: uia_event.c:499

Definition at line 499 of file uia_event.c.

◆ uia_desktop_node_rt_id

SAFEARRAY* uia_desktop_node_rt_id
static

Definition at line 26 of file uia_event.c.

Referenced by uia_get_desktop_rt_id(), and uia_init_desktop_rt_id().

◆ uia_event_adviser_vtbl

const IWineUiaEventAdviserVtbl uia_event_adviser_vtbl
static
Initial value:
= {
}
static HRESULT WINAPI uia_event_adviser_QueryInterface(IWineUiaEventAdviser *iface, REFIID riid, void **ppv)
Definition: uia_event.c:1306
static ULONG WINAPI uia_event_adviser_AddRef(IWineUiaEventAdviser *iface)
Definition: uia_event.c:1318
static HRESULT WINAPI uia_event_adviser_advise(IWineUiaEventAdviser *iface, BOOL advise_added, LONG_PTR huiaevent)
Definition: uia_event.c:1347
static ULONG WINAPI uia_event_adviser_Release(IWineUiaEventAdviser *iface)
Definition: uia_event.c:1327

Definition at line 1378 of file uia_event.c.

Referenced by uia_event_add_provider_event_adviser().

◆ uia_event_map

◆ uia_event_vtbl

const IWineUiaEventVtbl uia_event_vtbl
static
Initial value:
= {
}
static ULONG WINAPI uia_event_Release(IWineUiaEvent *iface)
Definition: uia_event.c:1036
static HRESULT WINAPI uia_event_QueryInterface(IWineUiaEvent *iface, REFIID riid, void **ppv)
Definition: uia_event.c:1015
static ULONG WINAPI uia_event_AddRef(IWineUiaEvent *iface)
Definition: uia_event.c:1027
static HRESULT WINAPI uia_event_set_event_data(IWineUiaEvent *iface, const GUID *event_guid, LONG scope, VARIANT runtime_id, IWineUiaEvent *event_iface)
Definition: uia_event.c:1118
static HRESULT WINAPI uia_event_raise_event(IWineUiaEvent *iface, VARIANT in_node, VARIANT in_nav_start_node)
Definition: uia_event.c:1146
static HRESULT WINAPI uia_event_advise_events(IWineUiaEvent *iface, BOOL advise_added, LONG adviser_start_idx)
Definition: uia_event.c:1076

Definition at line 1177 of file uia_event.c.

Referenced by create_uia_event(), and unsafe_impl_from_IWineUiaEvent().

◆ uia_proxy_event_sink_vtbl

const IProxyProviderWinEventSinkVtbl uia_proxy_event_sink_vtbl
static
Initial value:
= {
}
static ULONG WINAPI uia_proxy_win_event_sink_AddRef(IProxyProviderWinEventSink *iface)
Definition: uia_event.c:385
static HRESULT WINAPI uia_proxy_win_event_sink_AddAutomationEvent(IProxyProviderWinEventSink *iface, IRawElementProviderSimple *elprov, EVENTID event_id)
Definition: uia_event.c:419
static HRESULT WINAPI uia_proxy_win_event_sink_QueryInterface(IProxyProviderWinEventSink *iface, REFIID riid, void **obj)
Definition: uia_event.c:369
static HRESULT WINAPI uia_proxy_win_event_sink_AddStructureChangedEvent(IProxyProviderWinEventSink *iface, IRawElementProviderSimple *elprov, enum StructureChangeType structure_change_type, SAFEARRAY *runtime_id)
Definition: uia_event.c:441
static ULONG WINAPI uia_proxy_win_event_sink_Release(IProxyProviderWinEventSink *iface)
Definition: uia_event.c:395
static HRESULT WINAPI uia_proxy_win_event_sink_AddAutomationPropertyChangedEvent(IProxyProviderWinEventSink *iface, IRawElementProviderSimple *elprov, PROPERTYID prop_id, VARIANT new_value)
Definition: uia_event.c:412

Definition at line 448 of file uia_event.c.

Referenced by create_proxy_win_event_sink().

◆ uia_serverside_event_adviser_vtbl

const IWineUiaEventAdviserVtbl uia_serverside_event_adviser_vtbl
static
Initial value:
= {
}
static ULONG WINAPI uia_serverside_event_adviser_Release(IWineUiaEventAdviser *iface)
Definition: uia_event.c:1466
static HRESULT WINAPI uia_serverside_event_adviser_QueryInterface(IWineUiaEventAdviser *iface, REFIID riid, void **ppv)
Definition: uia_event.c:1445
static ULONG WINAPI uia_serverside_event_adviser_AddRef(IWineUiaEventAdviser *iface)
Definition: uia_event.c:1457
static HRESULT WINAPI uia_serverside_event_adviser_advise(IWineUiaEventAdviser *iface, BOOL advise_added, LONG_PTR huiaevent)
Definition: uia_event.c:1480

Definition at line 1512 of file uia_event.c.

Referenced by uia_event_add_serverside_event_adviser().