From 6720fa7bc2905f3c9fc3b7b2e2a5a04800f5fbec Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 24 Dec 2014 20:15:45 -0500 Subject: [PATCH] Started actually writing the accessibility code. Does not work yet. --- wintable/new/accessibility.h | 75 ++++++++++++++++++++++++++++++++++++ wintable/new/main.c | 9 +++++ 2 files changed, 84 insertions(+) create mode 100644 wintable/new/accessibility.h diff --git a/wintable/new/accessibility.h b/wintable/new/accessibility.h new file mode 100644 index 0000000..bb50dd3 --- /dev/null +++ b/wintable/new/accessibility.h @@ -0,0 +1,75 @@ +// 24 december 2014 + +struct tableAcc { + IAccessibleVtbl *vtbl; + ULONG refcount; + struct table *t; +}; + +static HRESULT STDMETHODCALLTYPE tableAccQueryInterface(IUnknown *this, REFIID riid, void **ppvObject) +{ + if (ppvObject == NULL) + return E_POINTER; + if (IsEqualIID(riid, IID_IUnknown) || +0)// IsEqualIID(riid, IID_IDispatch) +{// IsEqualIID(riid, IID_IAccessible) { + *ppvObject = (void *) this; + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; +} + +#define TA ((struct tableAcc *) this) + +// TODO use InterlockedIncrement()/InterlockedDecrement() for these? + +static ULONG STDMETHODCALLTYPE tableAccAddRef(IUnknown *this) +{ + TA->refcount++; + return TA->refcount; +} + +static ULONG STDMETHODCALLTYPE tableAccRelease(IUnknown *this) +{ + TA->refcount--; + if (TA->refcount == 0) { + tableFree(TA, "error freeing Table accessibility object"); + return 0; + } + return TA->refcount; +} + +static const IAccessibleVtbl tableAccVtbl = { + .QueryInterface = tableAccQueryInterface, + .AddRef = tableAccAddRef, + .Release = tableAccRelease, +}; + +static struct tableAcc *newTableAcc(struct table *t) +{ + struct tableAcc *ta; + + ta = (struct tableAcc *) tableAlloc(sizeof (struct tableAcc), "error creating Table accessibility object"); + ta->vtbl = &tableAccVtbl; + ta->vtbl->AddRef(vtbl); + ta->t = t; + return ta; +} + +static void freeTableAcc(struct tableAcc *ta) +{ + ta->t = NULL; + ta->vtbl->Release(ta); +} + +HANDLER(accessibilityHandler) +{ + if (uMsg != WM_GETOBJECT) + return FALSE; + if (wParam != OBJID_CLIENT) + return FALSE; + *lResult = LresultFromObject(IID_IUnknown, wParam, t->ta); + // TODO check *lResult + return TRUE; +} diff --git a/wintable/new/main.c b/wintable/new/main.c index 0baf096..89d3454 100644 --- a/wintable/new/main.c +++ b/wintable/new/main.c @@ -58,6 +58,9 @@ static void (*tablePanic)(const char *, DWORD) = NULL; static BOOL (*WINAPI tableTrackMouseEvent)(LPTRACKMOUSEEVENT); +// forward declaration +struct tableAcc; + struct table { HWND hwnd; HWND header; @@ -83,6 +86,7 @@ struct table { BOOL checkboxMouseDown; intptr_t checkboxMouseDownRow; intptr_t checkboxMouseDownColumn; + struct tableAcc *ta; }; #include "util.h" @@ -98,6 +102,7 @@ struct table { #include "resize.h" #include "draw.h" #include "api.h" +#include "accessibility.h" static const handlerfunc handlers[] = { eventHandlers, @@ -107,6 +112,7 @@ static const handlerfunc handlers[] = { apiHandlers, hscrollHandler, vscrollHandler, + accessibilityHandler, NULL, }; @@ -136,6 +142,7 @@ static LRESULT CALLBACK tableWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM t->selectedRow = -1; t->selectedColumn = -1; loadCheckboxThemeData(t); + t->ta = newTableAcc(t); initDummyTableStuff(t); SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) t); } @@ -146,6 +153,8 @@ initDummyTableStuff(t); printf("destroy\n"); // TODO free appropriate (after figuring this part out) components of t // TODO send EVENT_OBJECT_DESTROY events to accessibility listeners (when appropriate); see the note on proxy objects as well + freeTableAcc(t->ta); + t->ta = NULL; freeCheckboxThemeData(t); destroyHeader(t); tableFree(t, "error allocating internal Table data structure");