wined3d: Track synchronized buffer maps.
[wine.git] / dlls / oleacc / client.c
blobcc7b53ad0689c320de50fcf4c0e027a8bb575cee
1 /*
2 * Copyright 2014 Piotr Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define COBJMACROS
21 #include "oleacc_private.h"
23 #include "wine/unicode.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(oleacc);
28 typedef struct {
29 IAccessible IAccessible_iface;
30 IOleWindow IOleWindow_iface;
32 LONG ref;
34 HWND hwnd;
35 } Client;
37 static inline Client* impl_from_Client(IAccessible *iface)
39 return CONTAINING_RECORD(iface, Client, IAccessible_iface);
42 static HRESULT WINAPI Client_QueryInterface(IAccessible *iface, REFIID riid, void **ppv)
44 Client *This = impl_from_Client(iface);
46 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
48 if(IsEqualIID(riid, &IID_IAccessible) ||
49 IsEqualIID(riid, &IID_IDispatch) ||
50 IsEqualIID(riid, &IID_IUnknown)) {
51 *ppv = iface;
52 }else if(IsEqualIID(riid, &IID_IOleWindow)) {
53 *ppv = &This->IOleWindow_iface;
54 }else {
55 WARN("no interface: %s\n", debugstr_guid(riid));
56 *ppv = NULL;
57 return E_NOINTERFACE;
60 IAccessible_AddRef(iface);
61 return S_OK;
64 static ULONG WINAPI Client_AddRef(IAccessible *iface)
66 Client *This = impl_from_Client(iface);
67 ULONG ref = InterlockedIncrement(&This->ref);
69 TRACE("(%p) ref = %u\n", This, ref);
70 return ref;
73 static ULONG WINAPI Client_Release(IAccessible *iface)
75 Client *This = impl_from_Client(iface);
76 ULONG ref = InterlockedDecrement(&This->ref);
78 TRACE("(%p) ref = %u\n", This, ref);
80 if(!ref)
81 heap_free(This);
82 return ref;
85 static HRESULT WINAPI Client_GetTypeInfoCount(IAccessible *iface, UINT *pctinfo)
87 Client *This = impl_from_Client(iface);
88 FIXME("(%p)->(%p)\n", This, pctinfo);
89 return E_NOTIMPL;
92 static HRESULT WINAPI Client_GetTypeInfo(IAccessible *iface,
93 UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
95 Client *This = impl_from_Client(iface);
96 FIXME("(%p)->(%u %x %p)\n", This, iTInfo, lcid, ppTInfo);
97 return E_NOTIMPL;
100 static HRESULT WINAPI Client_GetIDsOfNames(IAccessible *iface, REFIID riid,
101 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
103 Client *This = impl_from_Client(iface);
104 FIXME("(%p)->(%s %p %u %x %p)\n", This, debugstr_guid(riid),
105 rgszNames, cNames, lcid, rgDispId);
106 return E_NOTIMPL;
109 static HRESULT WINAPI Client_Invoke(IAccessible *iface, DISPID dispIdMember,
110 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
111 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
113 Client *This = impl_from_Client(iface);
114 FIXME("(%p)->(%x %s %x %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
115 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
116 return E_NOTIMPL;
119 static HRESULT WINAPI Client_get_accParent(IAccessible *iface, IDispatch **ppdispParent)
121 Client *This = impl_from_Client(iface);
123 TRACE("(%p)->(%p)\n", This, ppdispParent);
125 return AccessibleObjectFromWindow(This->hwnd, OBJID_WINDOW,
126 &IID_IDispatch, (void**)ppdispParent);
129 static HRESULT WINAPI Client_get_accChildCount(IAccessible *iface, LONG *pcountChildren)
131 Client *This = impl_from_Client(iface);
132 HWND cur;
134 TRACE("(%p)->(%p)\n", This, pcountChildren);
136 *pcountChildren = 0;
137 for(cur = GetWindow(This->hwnd, GW_CHILD); cur; cur = GetWindow(cur, GW_HWNDNEXT))
138 (*pcountChildren)++;
140 return S_OK;
143 static HRESULT WINAPI Client_get_accChild(IAccessible *iface,
144 VARIANT varChildID, IDispatch **ppdispChild)
146 Client *This = impl_from_Client(iface);
147 FIXME("(%p)->(%s %p)\n", This, debugstr_variant(&varChildID), ppdispChild);
148 return E_NOTIMPL;
151 static HRESULT WINAPI Client_get_accName(IAccessible *iface, VARIANT varID, BSTR *pszName)
153 Client *This = impl_from_Client(iface);
154 WCHAR name[1024];
155 UINT i, len;
157 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszName);
159 *pszName = NULL;
160 if(convert_child_id(&varID) != CHILDID_SELF || !IsWindow(This->hwnd))
161 return E_INVALIDARG;
163 len = SendMessageW(This->hwnd, WM_GETTEXT, sizeof(name)/sizeof(WCHAR), (LPARAM)name);
164 if(!len)
165 return S_FALSE;
167 for(i=0; i<len; i++) {
168 if(name[i] == '&') {
169 len--;
170 memmove(name+i, name+i+1, (len-i)*sizeof(WCHAR));
171 break;
175 *pszName = SysAllocStringLen(name, len);
176 return *pszName ? S_OK : E_OUTOFMEMORY;
179 static HRESULT WINAPI Client_get_accValue(IAccessible *iface, VARIANT varID, BSTR *pszValue)
181 Client *This = impl_from_Client(iface);
183 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszValue);
185 *pszValue = NULL;
186 if(convert_child_id(&varID) != CHILDID_SELF)
187 return E_INVALIDARG;
188 return S_FALSE;
191 static HRESULT WINAPI Client_get_accDescription(IAccessible *iface,
192 VARIANT varID, BSTR *pszDescription)
194 Client *This = impl_from_Client(iface);
196 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszDescription);
198 *pszDescription = NULL;
199 if(convert_child_id(&varID) != CHILDID_SELF)
200 return E_INVALIDARG;
201 return S_FALSE;
204 static HRESULT WINAPI Client_get_accRole(IAccessible *iface, VARIANT varID, VARIANT *pvarRole)
206 Client *This = impl_from_Client(iface);
208 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarRole);
210 if(convert_child_id(&varID) != CHILDID_SELF) {
211 V_VT(pvarRole) = VT_EMPTY;
212 return E_INVALIDARG;
215 V_VT(pvarRole) = VT_I4;
216 V_I4(pvarRole) = ROLE_SYSTEM_CLIENT;
217 return S_OK;
220 static HRESULT WINAPI Client_get_accState(IAccessible *iface, VARIANT varID, VARIANT *pvarState)
222 Client *This = impl_from_Client(iface);
223 LONG style;
225 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pvarState);
227 if(convert_child_id(&varID) != CHILDID_SELF) {
228 V_VT(pvarState) = VT_EMPTY;
229 return E_INVALIDARG;
232 V_VT(pvarState) = VT_I4;
233 V_I4(pvarState) = 0;
235 style = GetWindowLongW(This->hwnd, GWL_STYLE);
236 if(style & WS_DISABLED)
237 V_I4(pvarState) |= STATE_SYSTEM_UNAVAILABLE;
238 else if(IsWindow(This->hwnd))
239 V_I4(pvarState) |= STATE_SYSTEM_FOCUSABLE;
240 if(GetFocus() == This->hwnd)
241 V_I4(pvarState) |= STATE_SYSTEM_FOCUSED;
242 if(!(style & WS_VISIBLE))
243 V_I4(pvarState) |= STATE_SYSTEM_INVISIBLE;
244 return S_OK;
247 static HRESULT WINAPI Client_get_accHelp(IAccessible *iface, VARIANT varID, BSTR *pszHelp)
249 Client *This = impl_from_Client(iface);
251 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszHelp);
253 *pszHelp = NULL;
254 if(convert_child_id(&varID) != CHILDID_SELF)
255 return E_INVALIDARG;
256 return S_FALSE;
259 static HRESULT WINAPI Client_get_accHelpTopic(IAccessible *iface,
260 BSTR *pszHelpFile, VARIANT varID, LONG *pidTopic)
262 Client *This = impl_from_Client(iface);
263 FIXME("(%p)->(%p %s %p)\n", This, pszHelpFile, debugstr_variant(&varID), pidTopic);
264 return E_NOTIMPL;
267 static HRESULT WINAPI Client_get_accKeyboardShortcut(IAccessible *iface,
268 VARIANT varID, BSTR *pszKeyboardShortcut)
270 static const WCHAR shortcut_fmt[] = {'A','l','t','+','!',0};
271 Client *This = impl_from_Client(iface);
272 WCHAR name[1024];
273 UINT i, len;
275 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszKeyboardShortcut);
277 *pszKeyboardShortcut = NULL;
278 if(convert_child_id(&varID) != CHILDID_SELF)
279 return E_INVALIDARG;
281 len = SendMessageW(This->hwnd, WM_GETTEXT, sizeof(name)/sizeof(WCHAR), (LPARAM)name);
282 for(i=0; i<len; i++) {
283 if(name[i] == '&')
284 break;
286 if(i+1 >= len)
287 return S_FALSE;
289 *pszKeyboardShortcut = SysAllocString(shortcut_fmt);
290 if(!*pszKeyboardShortcut)
291 return E_OUTOFMEMORY;
293 (*pszKeyboardShortcut)[4] = name[i+1];
294 return S_OK;
297 static HRESULT WINAPI Client_get_accFocus(IAccessible *iface, VARIANT *pvarID)
299 Client *This = impl_from_Client(iface);
300 FIXME("(%p)->(%p)\n", This, pvarID);
301 return E_NOTIMPL;
304 static HRESULT WINAPI Client_get_accSelection(IAccessible *iface, VARIANT *pvarID)
306 Client *This = impl_from_Client(iface);
307 FIXME("(%p)->(%p)\n", This, pvarID);
308 return E_NOTIMPL;
311 static HRESULT WINAPI Client_get_accDefaultAction(IAccessible *iface,
312 VARIANT varID, BSTR *pszDefaultAction)
314 Client *This = impl_from_Client(iface);
316 TRACE("(%p)->(%s %p)\n", This, debugstr_variant(&varID), pszDefaultAction);
318 *pszDefaultAction = NULL;
319 if(convert_child_id(&varID) != CHILDID_SELF)
320 return E_INVALIDARG;
321 return S_FALSE;
324 static HRESULT WINAPI Client_accSelect(IAccessible *iface, LONG flagsSelect, VARIANT varID)
326 Client *This = impl_from_Client(iface);
327 FIXME("(%p)->(%x %s)\n", This, flagsSelect, debugstr_variant(&varID));
328 return E_NOTIMPL;
331 static HRESULT WINAPI Client_accLocation(IAccessible *iface, LONG *pxLeft,
332 LONG *pyTop, LONG *pcxWidth, LONG *pcyHeight, VARIANT varID)
334 Client *This = impl_from_Client(iface);
335 RECT rect;
336 POINT pt;
338 TRACE("(%p)->(%p %p %p %p %s)\n", This, pxLeft, pyTop,
339 pcxWidth, pcyHeight, debugstr_variant(&varID));
341 *pxLeft = *pyTop = *pcxWidth = *pcyHeight = 0;
342 if(convert_child_id(&varID) != CHILDID_SELF)
343 return E_INVALIDARG;
345 if(!GetClientRect(This->hwnd, &rect))
346 return S_OK;
348 pt.x = rect.left,
349 pt.y = rect.top;
350 MapWindowPoints(This->hwnd, NULL, &pt, 1);
351 *pxLeft = pt.x;
352 *pyTop = pt.y;
354 pt.x = rect.right;
355 pt.y = rect.bottom;
356 MapWindowPoints(This->hwnd, NULL, &pt, 1);
357 *pcxWidth = pt.x - *pxLeft;
358 *pcyHeight = pt.y - *pyTop;
359 return S_OK;
362 static HRESULT WINAPI Client_accNavigate(IAccessible *iface,
363 LONG navDir, VARIANT varStart, VARIANT *pvarEnd)
365 Client *This = impl_from_Client(iface);
366 FIXME("(%p)->(%d %s %p)\n", This, navDir, debugstr_variant(&varStart), pvarEnd);
367 return E_NOTIMPL;
370 static HRESULT WINAPI Client_accHitTest(IAccessible *iface,
371 LONG xLeft, LONG yTop, VARIANT *pvarID)
373 Client *This = impl_from_Client(iface);
374 HWND child;
375 POINT pt;
377 TRACE("(%p)->(%d %d %p)\n", This, xLeft, yTop, pvarID);
379 V_VT(pvarID) = VT_I4;
380 V_I4(pvarID) = 0;
382 pt.x = xLeft;
383 pt.y = yTop;
384 if(!IsWindowVisible(This->hwnd) || !ScreenToClient(This->hwnd, &pt))
385 return S_OK;
387 child = ChildWindowFromPointEx(This->hwnd, pt, CWP_SKIPINVISIBLE);
388 if(!child || child==This->hwnd)
389 return S_OK;
391 V_VT(pvarID) = VT_DISPATCH;
392 return AccessibleObjectFromWindow(child, OBJID_WINDOW,
393 &IID_IDispatch, (void**)&V_DISPATCH(pvarID));
396 static HRESULT WINAPI Client_accDoDefaultAction(IAccessible *iface, VARIANT varID)
398 Client *This = impl_from_Client(iface);
399 FIXME("(%p)->(%s)\n", This, debugstr_variant(&varID));
400 return E_NOTIMPL;
403 static HRESULT WINAPI Client_put_accName(IAccessible *iface, VARIANT varID, BSTR pszName)
405 Client *This = impl_from_Client(iface);
406 FIXME("(%p)->(%s %s)\n", This, debugstr_variant(&varID), debugstr_w(pszName));
407 return E_NOTIMPL;
410 static HRESULT WINAPI Client_put_accValue(IAccessible *iface, VARIANT varID, BSTR pszValue)
412 Client *This = impl_from_Client(iface);
413 FIXME("(%p)->(%s %s)\n", This, debugstr_variant(&varID), debugstr_w(pszValue));
414 return E_NOTIMPL;
417 static const IAccessibleVtbl ClientVtbl = {
418 Client_QueryInterface,
419 Client_AddRef,
420 Client_Release,
421 Client_GetTypeInfoCount,
422 Client_GetTypeInfo,
423 Client_GetIDsOfNames,
424 Client_Invoke,
425 Client_get_accParent,
426 Client_get_accChildCount,
427 Client_get_accChild,
428 Client_get_accName,
429 Client_get_accValue,
430 Client_get_accDescription,
431 Client_get_accRole,
432 Client_get_accState,
433 Client_get_accHelp,
434 Client_get_accHelpTopic,
435 Client_get_accKeyboardShortcut,
436 Client_get_accFocus,
437 Client_get_accSelection,
438 Client_get_accDefaultAction,
439 Client_accSelect,
440 Client_accLocation,
441 Client_accNavigate,
442 Client_accHitTest,
443 Client_accDoDefaultAction,
444 Client_put_accName,
445 Client_put_accValue
448 static inline Client* impl_from_Client_OleWindow(IOleWindow *iface)
450 return CONTAINING_RECORD(iface, Client, IOleWindow_iface);
453 static HRESULT WINAPI Client_OleWindow_QueryInterface(IOleWindow *iface, REFIID riid, void **ppv)
455 Client *This = impl_from_Client_OleWindow(iface);
456 return IAccessible_QueryInterface(&This->IAccessible_iface, riid, ppv);
459 static ULONG WINAPI Client_OleWindow_AddRef(IOleWindow *iface)
461 Client *This = impl_from_Client_OleWindow(iface);
462 return IAccessible_AddRef(&This->IAccessible_iface);
465 static ULONG WINAPI Client_OleWindow_Release(IOleWindow *iface)
467 Client *This = impl_from_Client_OleWindow(iface);
468 return IAccessible_Release(&This->IAccessible_iface);
471 static HRESULT WINAPI Client_OleWindow_GetWindow(IOleWindow *iface, HWND *phwnd)
473 Client *This = impl_from_Client_OleWindow(iface);
475 TRACE("(%p)->(%p)\n", This, phwnd);
477 *phwnd = This->hwnd;
478 return S_OK;
481 static HRESULT WINAPI Client_OleWindow_ContextSensitiveHelp(IOleWindow *iface, BOOL fEnterMode)
483 Client *This = impl_from_Client_OleWindow(iface);
484 FIXME("(%p)->(%x)\n", This, fEnterMode);
485 return E_NOTIMPL;
488 static const IOleWindowVtbl ClientOleWindowVtbl = {
489 Client_OleWindow_QueryInterface,
490 Client_OleWindow_AddRef,
491 Client_OleWindow_Release,
492 Client_OleWindow_GetWindow,
493 Client_OleWindow_ContextSensitiveHelp
496 HRESULT create_client_object(HWND hwnd, const IID *iid, void **obj)
498 Client *client;
499 HRESULT hres;
501 if(!IsWindow(hwnd))
502 return E_FAIL;
504 client = heap_alloc_zero(sizeof(Client));
505 if(!client)
506 return E_OUTOFMEMORY;
508 client->IAccessible_iface.lpVtbl = &ClientVtbl;
509 client->IOleWindow_iface.lpVtbl = &ClientOleWindowVtbl;
510 client->ref = 1;
511 client->hwnd = hwnd;
513 hres = IAccessible_QueryInterface(&client->IAccessible_iface, iid, obj);
514 IAccessible_Release(&client->IAccessible_iface);
515 return hres;