diff -ruN orig/wxMac-2.8.12/Makefile.in wxMac-2.8.12/Makefile.in --- orig/wxMac-2.8.12/Makefile.in 2011-03-22 07:34:13.000000000 -0500 +++ wxMac-2.8.12/Makefile.in 2015-04-21 11:05:15.000000000 -0500 @@ -2170,6 +2170,7 @@ @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2@GUI_HDR = $(COND_TOOLKIT_GTK_TOOLKIT_VERSION_2_GUI_HDR) COND_TOOLKIT_MAC_GUI_HDR = \ wx/mac/accel.h \ + wx/mac/access.h \ wx/mac/aga.h \ wx/mac/app.h \ wx/mac/bitmap.h \ @@ -2254,6 +2255,7 @@ wx/mac/uma.h \ wx/mac/window.h \ wx/mac/carbon/accel.h \ + wx/mac/carbon/access.h \ wx/mac/carbon/aga.h \ wx/mac/carbon/app.h \ wx/mac/carbon/bitmap.h \ @@ -4314,6 +4316,7 @@ @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2@__GUI_SRC_OBJECTS = $(COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___GUI_SRC_OBJECTS) COND_TOOLKIT_MAC___GUI_SRC_OBJECTS = \ monodll_carbon_accel.o \ + monodll_carbon_access.o \ monodll_aga.o \ monodll_carbon_app.o \ monodll_carbon_bitmap.o \ @@ -6107,6 +6110,7 @@ @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2@__GUI_SRC_OBJECTS_1 = $(COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___GUI_SRC_OBJECTS_1) COND_TOOLKIT_MAC___GUI_SRC_OBJECTS_1 = \ monolib_carbon_accel.o \ + monolib_carbon_access.o \ monolib_aga.o \ monolib_carbon_app.o \ monolib_carbon_bitmap.o \ @@ -8180,6 +8184,7 @@ @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2@__GUI_SRC_OBJECTS_2 = $(COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___GUI_SRC_OBJECTS_2) COND_TOOLKIT_MAC___GUI_SRC_OBJECTS_2 = \ coredll_carbon_accel.o \ + coredll_carbon_access.o \ coredll_aga.o \ coredll_carbon_app.o \ coredll_carbon_bitmap.o \ @@ -9640,6 +9645,7 @@ @COND_TOOLKIT_GTK_TOOLKIT_VERSION_2@__GUI_SRC_OBJECTS_3 = $(COND_TOOLKIT_GTK_TOOLKIT_VERSION_2___GUI_SRC_OBJECTS_3) COND_TOOLKIT_MAC___GUI_SRC_OBJECTS_3 = \ corelib_carbon_accel.o \ + corelib_carbon_access.o \ corelib_aga.o \ corelib_carbon_app.o \ corelib_carbon_bitmap.o \ @@ -13708,6 +13714,9 @@ monodll_carbon_accel.o: $(srcdir)/src/mac/carbon/accel.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/mac/carbon/accel.cpp +monodll_carbon_access.o: $(srcdir)/src/mac/carbon/access.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/mac/carbon/access.cpp + monodll_aga.o: $(srcdir)/src/mac/carbon/aga.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/mac/carbon/aga.cpp @@ -17845,6 +17854,9 @@ monolib_carbon_accel.o: $(srcdir)/src/mac/carbon/accel.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/mac/carbon/accel.cpp +monolib_carbon_access.o: $(srcdir)/src/mac/carbon/access.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/mac/carbon/access.cpp + monolib_aga.o: $(srcdir)/src/mac/carbon/aga.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/mac/carbon/aga.cpp @@ -22930,6 +22942,9 @@ coredll_carbon_accel.o: $(srcdir)/src/mac/carbon/accel.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/mac/carbon/accel.cpp +coredll_carbon_access.o: $(srcdir)/src/mac/carbon/access.cpp $(COREDLL_ODEP) + $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/mac/carbon/access.cpp + coredll_aga.o: $(srcdir)/src/mac/carbon/aga.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/mac/carbon/aga.cpp @@ -25894,6 +25909,9 @@ corelib_carbon_accel.o: $(srcdir)/src/mac/carbon/accel.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/mac/carbon/accel.cpp +corelib_carbon_access.o: $(srcdir)/src/mac/carbon/access.cpp $(CORELIB_ODEP) + $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/mac/carbon/access.cpp + corelib_aga.o: $(srcdir)/src/mac/carbon/aga.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/mac/carbon/aga.cpp diff -ruN orig/wxMac-2.8.12/include/wx/access.h wxMac-2.8.12/include/wx/access.h --- orig/wxMac-2.8.12/include/wx/access.h 2011-03-22 07:32:57.000000000 -0500 +++ wxMac-2.8.12/include/wx/access.h 2015-04-21 11:05:15.000000000 -0500 @@ -371,6 +371,10 @@ #include "wx/msw/ole/access.h" #endif +#if defined(__WXMAC__) + #include "wx/mac/access.h" +#endif + #endif // wxUSE_ACCESSIBILITY #endif // _WX_ACCESSBASE_H_ diff -ruN orig/wxMac-2.8.12/include/wx/mac/access.h wxMac-2.8.12/include/wx/mac/access.h --- orig/wxMac-2.8.12/include/wx/mac/access.h 1969-12-31 18:00:00.000000000 -0600 +++ wxMac-2.8.12/include/wx/mac/access.h 2015-04-21 11:05:15.000000000 -0500 @@ -0,0 +1,5 @@ +#ifdef __WXMAC_CLASSIC__ +#error "wxAccessible not implemented for Classic build." +#else +#include "wx/mac/carbon/access.h" +#endif diff -ruN orig/wxMac-2.8.12/include/wx/mac/carbon/access.h wxMac-2.8.12/include/wx/mac/carbon/access.h --- orig/wxMac-2.8.12/include/wx/mac/carbon/access.h 1969-12-31 18:00:00.000000000 -0600 +++ wxMac-2.8.12/include/wx/mac/carbon/access.h 2015-04-21 11:05:15.000000000 -0500 @@ -0,0 +1,140 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: mac/carbon/access.h +// Purpose: declaration of the wxAccessible class +// Author: Julian Smart +// Modified by: Leland Lucius +// Created: 2009-11-29 +// RCS-ID: $Id: access.h 35650 2005-09-23 12:56:45Z MR $ +// Copyright: (c) 2003 Julian Smart +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_ACCESS_H_ +#define _WX_ACCESS_H_ + +#if wxUSE_ACCESSIBILITY + +#ifdef __DARWIN__ + #include + #include +#else + #include + #include +#endif + +// ---------------------------------------------------------------------------- +// forward declarations +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_FWD_CORE wxWindow; +class WXDLLIMPEXP_FWD_CORE wxMacCarbonEvent; +class WXDLLIMPEXP_FWD_CORE wxAccessibleMac; + +// ---------------------------------------------------------------------------- +// macros +// ---------------------------------------------------------------------------- + +// ---------------------------------------------------------------------------- +// wxAccessible implements accessibility behaviour. +// ---------------------------------------------------------------------------- +class WXDLLEXPORT wxAccessible : public wxAccessibleBase +{ +public: + wxAccessible(wxWindow *win = NULL); + virtual ~wxAccessible(); + +// Overridables + + virtual wxAccStatus GetExtendedRole(int childId, wxString *role, wxString *subrole); + +// Accessors + + wxAccessibleMac *GetAccessibleMac() {return m_accessiblemac;}; + +// Operations + + // Sends an event when something changes in an accessible object. + static void NotifyEvent(int eventType, wxWindow* window, wxAccObject objectType, + int objectId); + +protected: + void Init(); + +private: + wxAccessibleMac *m_accessiblemac; + + DECLARE_NO_COPY_CLASS(wxAccessible) +}; + +// ---------------------------------------------------------------------------- +// wxAccessible implements accessibility behaviour. +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxAccessibleMac +{ +public: + wxAccessibleMac(); + wxAccessibleMac(wxAccessible *acc, bool emulated = false); + virtual ~wxAccessibleMac(); + +// Overridables + + virtual CFStringRef GetDefaultRole(); + virtual void SetDefaultRole(const CFStringRef role); + virtual bool HasDefaultRole(); + + virtual CFStringRef GetDefaultSubrole(); + virtual void SetDefaultSubrole(const CFStringRef subrole); + virtual bool HasDefaultSubrole(); + + virtual void SetNative(bool native); + virtual bool IsNative(); + + virtual OSStatus GetAllAttributeNames(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetAllParameterizedAttributeNames(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetNamedAttribute(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus IsNamedAttributeSettable(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus SetNamedAttribute(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetAllActionNames(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetNamedActionDescription(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus PerformNamedAction(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetChildAtPoint(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetFocusedChild(wxMacCarbonEvent & event, UInt64 id); + +// Accessors + + wxAccessible *GetAccessible() {return m_accessible;}; + void SetAccessible(wxAccessible *accessible) {m_accessible = accessible;}; + + bool IsFullyEmulated() {return m_emulated;}; + void SetFullyEmulated(bool emulated) {m_emulated = emulated;}; + +// Operations + + CFStringRef TranslateRole(UInt64 id, CFStringRef *subrole); + + // Sends an event when something changes in an accessible object. + static void NotifyEvent(int eventType, wxWindow* window, wxAccObject objectType, + int objectId); + +protected: + void Init(wxAccessible *acc, bool emulated = false); + +private: + wxAccessible *m_accessible; + + EventHandlerRef m_evthandlerRef; + + CFStringRef m_roleRef; + CFStringRef m_subroleRef; + + bool m_native; + bool m_emulated; + + DECLARE_NO_COPY_CLASS(wxAccessibleMac) +}; + +#endif //wxUSE_ACCESSIBILITY + +#endif //_WX_ACCESS_H_ + diff -ruN orig/wxMac-2.8.12/src/common/matrix.cpp wxMac-2.8.12/src/common/matrix.cpp --- orig/wxMac-2.8.12/src/common/matrix.cpp 2011-03-22 07:33:13.000000000 -0500 +++ wxMac-2.8.12/src/common/matrix.cpp 2015-05-15 12:14:53.000000000 -0500 @@ -25,7 +25,7 @@ #include "wx/math.h" #endif -static const double pi = M_PI; +//static const double pi = M_PI; wxTransformMatrix::wxTransformMatrix(void) { diff -ruN orig/wxMac-2.8.12/src/mac/carbon/access.cpp wxMac-2.8.12/src/mac/carbon/access.cpp --- orig/wxMac-2.8.12/src/mac/carbon/access.cpp 1969-12-31 18:00:00.000000000 -0600 +++ wxMac-2.8.12/src/mac/carbon/access.cpp 2015-04-21 16:07:03.000000000 -0500 @@ -0,0 +1,3919 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/msw/ole/access.cpp +// Purpose: implementation of wxIAccessible and wxAccessible +// Author: Julian Smart +// Modified by: +// Created: 2003-02-12 +// RCS-ID: $Id: access.cpp 51833 2008-02-16 11:15:07Z JS $ +// Copyright: (c) 2003 Julian Smart +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if wxUSE_ACCESSIBILITY + +#include "wx/access.h" + +#ifndef WX_PRECOMP + #include "wx/window.h" + #include "wx/log.h" +#endif + +#include "wx/app.h" +#include "wx/combo.h" +#include "wx/combobox.h" +#include "wx/datectrl.h" +#include "wx/frame.h" +#include "wx/listctrl.h" +#include "wx/panel.h" +#include "wx/slider.h" +#include "wx/statbmp.h" +#include "wx/statbox.h" +#include "wx/stattext.h" +#include "wx/statusbr.h" +#include "wx/treebook.h" +#include "wx/treectrl.h" + +#if wxUSE_TOOLTIPS +#include "wx/tooltip.h" +#endif + +#include "wx/mac/uma.h" +#include "wx/mac/carbon/private/mactext.h" + +#include "wx/access.h" + +#define MAC_SCROLLBAR_SIZE 15 +#define MAC_SMALL_SCROLLBAR_SIZE 11 + +#if TARGET_API_MAC_OSX +#ifndef __HIVIEW__ + #include +#endif +#endif + +#ifndef CHILDID_SELF +#define CHILDID_SELF 0 +#endif + +#ifndef OBJID_CLIENT +#define OBJID_CLIENT 0xFFFFFFFC +#endif + +#define kEventParamBypassProbe 'WXBP' + +static const EventTypeSpec eventList[] = +{ + { kEventClassAccessibility , kEventAccessibleGetChildAtPoint }, + { kEventClassAccessibility , kEventAccessibleGetFocusedChild }, + { kEventClassAccessibility , kEventAccessibleGetAllAttributeNames }, + { kEventClassAccessibility , kEventAccessibleGetAllParameterizedAttributeNames }, + { kEventClassAccessibility , kEventAccessibleGetNamedAttribute }, + { kEventClassAccessibility , kEventAccessibleIsNamedAttributeSettable }, + { kEventClassAccessibility , kEventAccessibleSetNamedAttribute }, + { kEventClassAccessibility , kEventAccessibleGetAllActionNames }, + { kEventClassAccessibility , kEventAccessiblePerformNamedAction }, + { kEventClassAccessibility , kEventAccessibleGetNamedActionDescription }, +}; + +static const EventTypeSpec focusedChildList[] = +{ + { kEventClassAccessibility , kEventAccessibleGetFocusedChild }, +}; + +static const EventTypeSpec namedAttrsList[] = +{ + { kEventClassAccessibility , kEventAccessibleGetAllAttributeNames }, + { kEventClassAccessibility , kEventAccessibleGetNamedAttribute }, + { kEventClassAccessibility , kEventAccessibleIsNamedAttributeSettable }, + { kEventClassAccessibility , kEventAccessibleSetNamedAttribute }, +}; + +static pascal OSStatus wxMacAccessibleEventHandler(EventHandlerCallRef handlerRef, EventRef eventRef, void *data) +{ + wxMacCarbonEvent event(eventRef); + wxAccessibleMac *macc = (wxAccessibleMac *) data; + wxAccessible *acc = macc->GetAccessible(); + wxWindowMac *w = acc->GetWindow(); + OSStatus result; + + if (event.GetClass() != kEventClassAccessibility) { + return eventNotHandledErr; + } + + Boolean bypass = false; + result = event.GetParameter(kEventParamBypassProbe, + typeBoolean, + sizeof(bypass), + &bypass); + if (result == noErr) { + return eventNotHandledErr; + } + + AXUIElementRef element = NULL; + result = event.GetParameter(kEventParamAccessibleObject, + typeCFTypeRef, + sizeof(element), + &element); + if (result != noErr) { + return result; + } + + wxASSERT(element != NULL); + if (element == NULL) { + return result; + } + + UInt64 id; + AXUIElementGetIdentifier(element, &id); + + if (!macc->IsFullyEmulated()) { + if (id > 0) { + wxAccessible *cacc = NULL; + if (acc->GetChild(id, &cacc) == wxACC_OK && cacc != NULL && cacc != acc) { + acc = cacc; + w = acc->GetWindow(); + id = 0; + } + } + } + + EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent(); + EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef(); + wxTheApp->MacSetCurrentEvent(eventRef, handlerRef); + + switch (event.GetKind()) + { + case kEventAccessibleGetChildAtPoint: + result = macc->GetChildAtPoint(event, id); + break; + + case kEventAccessibleGetFocusedChild: + result = macc->GetFocusedChild(event, id); + break; + + case kEventAccessibleGetAllAttributeNames: + result = macc->GetAllAttributeNames(event, id); + break; + + case kEventAccessibleGetAllParameterizedAttributeNames: + result = macc->GetAllParameterizedAttributeNames(event, id); + break; + + case kEventAccessibleGetNamedAttribute: + result = macc->GetNamedAttribute(event, id); + break; + + case kEventAccessibleGetAllActionNames: + result = macc->GetAllActionNames(event, id); + break; + + case kEventAccessiblePerformNamedAction: + result = macc->PerformNamedAction(event, id); + break; + + case kEventAccessibleGetNamedActionDescription: + result = macc->GetNamedActionDescription(event, id); + break; + + case kEventAccessibleIsNamedAttributeSettable: + result = macc->IsNamedAttributeSettable(event, id); + break; + + case kEventAccessibleSetNamedAttribute: + result = macc->SetNamedAttribute(event, id); + break; + + default: + result = eventNotHandledErr; + break; + } + + wxTheApp->MacSetCurrentEvent(formerEvent, formerEventHandlerCallRef); + + return result; +} + +DEFINE_ONE_SHOT_HANDLER_GETTER(wxMacAccessibleEventHandler); + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +static OSStatus GetArray(wxMacCarbonEvent & event, CFMutableArrayRef & array, + int parm = kEventParamAccessibleAttributeValue) +{ + OSStatus result; + + array = NULL; + + result = event.GetParameter(parm, + typeCFTypeRef, + sizeof(array), + &array); + + if (result != noErr || array == NULL) { + array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + + if (array == NULL) { + return eventNotHandledErr; + } + + result = event.SetParameter(parm, + typeCFMutableArrayRef, + sizeof(array), + &array); + + CFRelease(array); + } + + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +static OSStatus SetElement(wxMacCarbonEvent & event, HIObjectRef objectRef, + UInt64 id, int parm) +{ + OSStatus result = eventNotHandledErr; + AXUIElementRef elem; + + elem = AXUIElementCreateWithHIObjectAndIdentifier(objectRef, id); + if (elem) { + result = event.SetParameter(parm, + typeCFTypeRef, + sizeof(elem), + &elem); + CFRelease(elem); + } + + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +static OSStatus AddElement(wxMacCarbonEvent & event, HIObjectRef objectRef, + UInt64 id, CFMutableArrayRef array) +{ + OSStatus result = eventNotHandledErr; + AXUIElementRef elem; + + elem = AXUIElementCreateWithHIObjectAndIdentifier(objectRef, id); + if (elem) { + CFArrayAppendValue(array, elem); + + CFRelease(elem); + + result = noErr; + } + + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +EventHandlerUPP GetwxTextCtrlAxEventHandlerUPP(); +EventHandlerUPP GetwxTextCtrlAxChildEventHandlerUPP(); + +class wxTextCtrlAx: public wxAccessibleMac +{ +public: + wxTextCtrlAx(wxAccessible *acc) + : wxAccessibleMac(), + m_accobjRef(NULL), + m_textHandlerRef(NULL), + m_childHandlerRef(NULL) + { + SetAccessible(acc); + + wxTextCtrl *tc = wxDynamicCast(acc->GetWindow(), wxTextCtrl); + ControlRef control = (ControlRef) tc->GetHandle(); + HIViewRef subview = HIViewGetFirstSubview(control); + + if (subview && HIObjectIsOfClass((HIObjectRef) subview, kHIScrollBarClassID)) { + subview = HIViewGetNextView(subview); + } + + if (subview && HIObjectIsOfClass((HIObjectRef) subview, kHIScrollBarClassID)) { + subview = HIViewGetNextView(subview); + } + + if (subview && HIObjectIsOfClass((HIObjectRef) subview, kHITextViewClassID)) { + TXNObject txn = HITextViewGetTXNObject((ControlRef)subview); + if (txn && TXNGetAccessibilityHIObject(txn, &m_accobjRef) == noErr) { + InstallControlEventHandler(subview, + GetwxTextCtrlAxEventHandlerUPP(), + GetEventTypeCount(focusedChildList), + focusedChildList, + this, + &m_textHandlerRef); + InstallHIObjectEventHandler(m_accobjRef, + GetwxTextCtrlAxChildEventHandlerUPP(), + GetEventTypeCount(namedAttrsList), + namedAttrsList, + this, + &m_childHandlerRef); + } + } + + SetNative(true); + } + + virtual ~wxTextCtrlAx() + { + if (m_textHandlerRef != NULL) { + ::RemoveEventHandler(m_textHandlerRef); + m_textHandlerRef = NULL; + } + + if (m_childHandlerRef != NULL) { + ::RemoveEventHandler(m_childHandlerRef); + m_childHandlerRef = NULL; + } + } + + HIObjectRef m_accobjRef; + EventHandlerRef m_textHandlerRef; + EventHandlerRef m_childHandlerRef; +}; + +static pascal OSStatus wxTextCtrlAxEventHandler(EventHandlerCallRef handlerRef, EventRef eventRef, void *data) +{ + wxMacCarbonEvent event(eventRef); + wxTextCtrlAx *macc = (wxTextCtrlAx *) data; + + return SetElement(event, macc->m_accobjRef, 0, kEventParamAccessibleChild); +} + +DEFINE_ONE_SHOT_HANDLER_GETTER(wxTextCtrlAxEventHandler); + +static pascal OSStatus wxTextCtrlAxChildEventHandler(EventHandlerCallRef handlerRef, EventRef eventRef, void *data) +{ + wxMacCarbonEvent event(eventRef); + wxTextCtrlAx *macc = (wxTextCtrlAx *) data; + wxTextCtrl *tc = wxDynamicCast(macc->GetAccessible()->GetWindow(), wxTextCtrl); + OSStatus result = eventNotHandledErr; + + switch (event.GetKind()) + { + case kEventAccessibleGetAllAttributeNames: + { + CFMutableArrayRef array; + + if (GetArray(event, array, kEventParamAccessibleAttributeNames) != noErr) { + return result; + } + + CFArrayAppendValue(array, kAXRoleAttribute); + CFArrayAppendValue(array, kAXRoleDescriptionAttribute); + CFArrayAppendValue(array, kAXParentAttribute); + CFArrayAppendValue(array, kAXWindowAttribute); + CFArrayAppendValue(array, kAXTopLevelUIElementAttribute); + CFArrayAppendValue(array, kAXPositionAttribute); + CFArrayAppendValue(array, kAXSizeAttribute); + + result = eventNotHandledErr; + } + break; + + case kEventAccessibleGetNamedAttribute: + { + CFStringRef attr; + + require_noerr(event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr), ParameterError); + + if (false) + { + } + else if (CFStringCompare(attr, kAXRoleAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role = kAXTextFieldRole; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(role), + &role); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXRoleDescriptionAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role = kAXTextFieldRole; + CFStringRef desc; + + desc = HICopyAccessibilityRoleDescription(role, NULL); + if (desc) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(desc), + &desc); + + CFRelease(desc); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXParentAttribute, 0) == kCFCompareEqualTo) { + wxWindow *parent = tc->GetParent(); + if (parent) { + HIObjectRef objectRef = (HIObjectRef) parent->GetHandle(); + + result = SetElement(event, objectRef, 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXWindowAttribute, 0) == kCFCompareEqualTo) { + wxWindow *tw = wxGetTopLevelParent(tc); + + if (tw != tc) { + result = SetElement(event, (HIObjectRef) tw->GetHandle(), 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXTopLevelUIElementAttribute, 0) == kCFCompareEqualTo) { + wxWindow *tw = wxGetTopLevelParent(tc); + + if (tw != tc) { + result = SetElement(event, (HIObjectRef) tw->GetHandle(), 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXPositionAttribute, 0) == kCFCompareEqualTo) { + wxRect wxrect = tc->GetRect(); + + wxWindow *parent = tc->GetParent(); + if (parent) { + parent->ClientToScreen(&wxrect.x, &wxrect.y); + } + + HIPoint point = {wxrect.x, wxrect.y}; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeHIPoint, + sizeof(point), + &point); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXSizeAttribute, 0 ) == kCFCompareEqualTo) { + wxRect wxrect = tc->GetRect(); + HISize size = {wxrect.width, wxrect.height}; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeHISize, + sizeof(size), + &size); + + require_noerr(result, ParameterError); + } + else { + result = eventNotHandledErr; + } + } + break; + } + +ParameterError: + return result; +} + +DEFINE_ONE_SHOT_HANDLER_GETTER(wxTextCtrlAxChildEventHandler); + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +static pascal OSStatus wxListCtrlAxEventHandler(EventHandlerCallRef handlerRef, EventRef eventRef, void *data) +{ + wxMacCarbonEvent event(eventRef); + wxAccessibleMac *macc = (wxAccessibleMac *) data; + wxListCtrl *lc = wxDynamicCast(macc->GetAccessible()->GetWindow(), wxListCtrl); + OSStatus result = CallNextEventHandler(handlerRef, eventRef); + + AXUIElementRef elem = NULL;; + if (event.GetParameter(kEventParamAccessibleObject, + typeCFTypeRef, + sizeof(elem), + &elem) != noErr) { + return result; + } + + ControlRef ctrl; + UInt64 id; + + ctrl = (ControlRef) AXUIElementGetHIObject(elem); + AXUIElementGetIdentifier(elem, &id); + + DataBrowserAccessibilityItemInfo info; + memset(&info, 0, sizeof(info)); + AXUIElementGetDataBrowserItemInfo(elem, ctrl, 1, &info); + + DataBrowserPropertyID prop = info.u.v1.columnProperty; + long row = info.u.v1.rowIndex; + long col = info.u.v1.columnIndex; + bool isoutline = info.u.v1.item == kDataBrowserNoItem; + bool isrow = info.u.v1.item != kDataBrowserNoItem && prop < kMinColumnId; + bool isitem = prop >= kMinColumnId; + + if (isoutline) { + switch (event.GetKind()) + { + case kEventAccessibleGetFocusedChild: + { + if (id == 0) { + elem = AXUIElementCreateWithDataBrowserAndItemInfo(ctrl, &info); + + result = event.SetParameter(kEventParamAccessibleChild, + typeCFTypeRef, + sizeof(elem), + &elem); + + require_noerr(result, ParameterError); + } + } + break; + + case kEventAccessibleGetAllAttributeNames: + { + if (id == 0) { + CFMutableArrayRef array; + + result = GetArray(event, array, kEventParamAccessibleAttributeNames); + + require_noerr(result, ParameterError); + + CFArrayAppendValue(array, kAXFocusedAttribute); + } + } + break; + + case kEventAccessibleGetNamedAttribute: + { + CFStringRef attr; + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr); + + require_noerr(result, ParameterError); + + if (CFStringCompare(attr, kAXParentAttribute, 0) == kCFCompareEqualTo) { + if (id == 1) { + result = SetElement(event, (HIObjectRef) lc->GetHandle(), 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + if (id == 0) { + Boolean state = false; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + } + } + break; + } + } + else if (isrow) { + switch (event.GetKind()) + { + case kEventAccessibleGetAllAttributeNames: + { + CFMutableArrayRef array; + + require_noerr(GetArray(event, array, kEventParamAccessibleAttributeNames), + ParameterError); + + CFArrayAppendValue(array, kAXSubroleAttribute); + } + break; + + case kEventAccessibleGetNamedAttribute: + { + CFStringRef attr; + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr); + + require_noerr(result, ParameterError); + + if (CFStringCompare(attr, kAXSubroleAttribute, 0) == kCFCompareEqualTo) { + CFStringRef subrole = kAXOutlineRowSubrole; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(subrole), + &subrole); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXRoleDescriptionAttribute, 0) == kCFCompareEqualTo) { + CFStringRef desc; + + desc = HICopyAccessibilityRoleDescription(kAXRowRole, kAXOutlineRowSubrole); + if (desc) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(desc), + &desc); + + CFRelease(desc); + + require_noerr(result, ParameterError); + } + } + } + break; + } + } + else if (isitem) { + switch (event.GetKind()) + { + case kEventAccessibleGetAllAttributeNames: + { + CFMutableArrayRef array; + + require_noerr(GetArray(event, array, kEventParamAccessibleAttributeNames), + ParameterError); + + CFArrayRemoveAllValues(array); + CFArrayAppendValue(array, kAXRoleAttribute); + CFArrayAppendValue(array, kAXRoleDescriptionAttribute); + CFArrayAppendValue(array, kAXParentAttribute); + CFArrayAppendValue(array, kAXWindowAttribute); + CFArrayAppendValue(array, kAXTopLevelUIElementAttribute); + CFArrayAppendValue(array, kAXPositionAttribute); + CFArrayAppendValue(array, kAXSizeAttribute); + + CFArrayAppendValue(array, kAXValueAttribute); + CFArrayAppendValue(array, kAXFocusedAttribute); + CFArrayAppendValue(array, kAXEnabledAttribute); + CFArrayAppendValue(array, kAXVisibleCharacterRangeAttribute); + CFArrayAppendValue(array, kAXSelectedTextAttribute); + CFArrayAppendValue(array, kAXNumberOfCharactersAttribute); + CFArrayAppendValue(array, kAXSelectedTextRangeAttribute); + } + break; + + case kEventAccessibleGetNamedAttribute: + { + CFStringRef attr; + + require_noerr(event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr), ParameterError); + + if (CFStringCompare(attr, kAXRoleAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role = (prop == kMinColumnId ? kAXTextFieldRole : kAXStaticTextRole); + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(role), + &role); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXRoleDescriptionAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role = (prop == kMinColumnId ? kAXTextFieldRole : kAXStaticTextRole); + CFStringRef desc; + + desc = HICopyAccessibilityRoleDescription(role, NULL); + if (desc) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(desc), + &desc); + + CFRelease(desc); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXValueAttribute, 0) == kCFCompareEqualTo) { + wxListItem item; + item.SetId(row); + item.SetColumn(col); + item.SetMask(wxLIST_MASK_TEXT); + if (lc->GetItem(item)) { + wxMacCFStringHolder holder(item.GetText()); + const CFStringRef string = holder; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(string), + &string); + + require_noerr(result, ParameterError); + } + else { + wxASSERT_MSG(false, wxT("INVALID ITEM IN VALUE!!!!!!!!!!!!!!!!!!!!!!!\n")); + } + } + else if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + Boolean state = false; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXEnabledAttribute, 0) == kCFCompareEqualTo) { + Boolean state = true; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXVisibleCharacterRangeAttribute, 0) == kCFCompareEqualTo) { + wxListItem item; + item.SetId(row); + item.SetColumn(col); + item.SetMask(wxLIST_MASK_TEXT); + if (lc->GetItem(item)) { + CFRange range = CFRangeMake(0, item.GetText().Length()); + AXValueRef valRef = AXValueCreate(kAXValueCFRangeType, &range); + + if (valRef) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFTypeRef, + sizeof(valRef), + &valRef); + + CFRelease(valRef); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXNumberOfCharactersAttribute, 0) == kCFCompareEqualTo) { + wxListItem item; + item.SetId(row); + item.SetColumn(col); + item.SetMask(wxLIST_MASK_TEXT); + if (lc->GetItem(item)) { + CFNumberRef numRef; + int cnt = item.GetText().Length(); + + numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &cnt); + if (numRef) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFTypeRef, + sizeof(numRef), + &numRef); + + CFRelease(numRef); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXSelectedTextAttribute, 0) == kCFCompareEqualTo) { + result = noErr; + } + else if (CFStringCompare(attr, kAXSelectedTextRangeAttribute, 0) == kCFCompareEqualTo) { + result = noErr; + } + } + break; + + case kEventAccessibleIsNamedAttributeSettable: + { + CFStringRef attr; + Boolean settable = false; + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr); + + if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + settable = true; + } + else if (CFStringCompare(attr, kAXValueAttribute, 0) == kCFCompareEqualTo) { + settable = true; + } + + result = event.SetParameter(kEventParamAccessibleAttributeSettable, + typeBoolean, + sizeof(settable), + &settable); + + require_noerr(result, ParameterError); + } + break; + + case kEventAccessibleSetNamedAttribute: + { + + CFStringRef attr; + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr); + + CFShow(attr); + wxASSERT_MSG(false, wxT("SETNAMED WAS CALLED FOR ITEM")); + } + break; + } + } + +ParameterError: + return result; +} + +DEFINE_ONE_SHOT_HANDLER_GETTER(wxListCtrlAxEventHandler); + +class wxListCtrlAx: public wxAccessibleMac, wxEvtHandler +{ +public: + wxListCtrlAx(wxAccessible *acc) + : wxAccessibleMac(), + m_acchand(NULL) + { + SetAccessible(acc); + + wxListCtrl *lc = wxDynamicCast(acc->GetWindow(), wxListCtrl); + + InstallControlEventHandler((ControlRef) lc->GetHandle(), + GetwxListCtrlAxEventHandlerUPP(), + GetEventTypeCount(eventList), + eventList, + this, + &m_acchand); + + SetNative(true); + } + + virtual ~wxListCtrlAx() + { + if (m_acchand != NULL) { + ::RemoveEventHandler(m_acchand); + m_acchand = NULL; + } + } + + EventHandlerRef m_acchand; +}; + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +static pascal OSStatus wxSliderAxEventHandler(EventHandlerCallRef handlerRef, EventRef eventRef, void *data) +{ + wxMacCarbonEvent event(eventRef); + OSStatus result = eventNotHandledErr; + + switch (event.GetKind()) + { + case kEventAccessibleGetFocusedChild: + { + result = noErr; + } + break; + } + +ParameterError: + return result; +} + +DEFINE_ONE_SHOT_HANDLER_GETTER(wxSliderAxEventHandler); + +class wxSliderAx: public wxAccessibleMac +{ +public: + wxSliderAx(wxAccessible *acc) + : wxAccessibleMac(), + m_acchand(NULL) + { + SetAccessible(acc); + + wxSlider *s = wxDynamicCast(acc->GetWindow(), wxSlider); + + InstallControlEventHandler((ControlRef) s->GetHandle(), + GetwxSliderAxEventHandlerUPP(), + GetEventTypeCount(focusedChildList), + focusedChildList, + this, + &m_acchand); + + SetNative(true); + } + + virtual ~wxSliderAx() + { + if (m_acchand != NULL) { + ::RemoveEventHandler(m_acchand); + m_acchand = NULL; + } + } + + EventHandlerRef m_acchand; +}; + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +class wxTreebookAx: public wxAccessibleMac +{ +public: + wxTreebookAx(wxAccessible *acc) + : wxAccessibleMac(acc, true) + { + } + + virtual ~wxTreebookAx() + { + } + + virtual OSStatus GetFocusedChild(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetChildAtPoint(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetAllAttributeNames(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetNamedAttribute(wxMacCarbonEvent & event, UInt64 id); +}; + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetChildAtPoint event +// ---------------------------------------------------------------------------- +OSStatus wxTreebookAx::GetFocusedChild(wxMacCarbonEvent & event, UInt64 id) +{ + wxTreebook *tb = wxDynamicCast(GetAccessible()->GetWindow(), wxTreebook); + wxWindow *last; + wxWindow *cur; + OSStatus result; + + // + // Determine the immediate child of the Treebook that either has the + // current focus or whose progeny has the focus. + // + + last = NULL; + cur = wxWindow::FindFocus(); + while (cur && cur != tb) { + last = cur; + cur = cur->GetParent(); + } + + // Focused window is not a descendant of this one + if (!cur || !last) { + return noErr; + } + + // Focused window is a descendant so return immediate child + result = SetElement(event, (HIObjectRef) last->GetHandle(), 0, + kEventParamAccessibleChild); + + require_noerr(result, ParameterError); + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetChildAtPoint event +// ---------------------------------------------------------------------------- +OSStatus wxTreebookAx::GetChildAtPoint(wxMacCarbonEvent & event, UInt64 id) +{ + wxTreebook *tb = wxDynamicCast(GetAccessible()->GetWindow(), wxTreebook); + wxWindow *last; + wxWindow *cur; + OSStatus result; + HIPoint pt; + wxPoint p; + + result = event.GetParameter(kEventParamMouseLocation, + typeHIPoint, + sizeof(pt), + &pt); + + require_noerr(result, ParameterError); + + p.x = (int) pt.x; + p.y = (int) pt.y; + + last = NULL; + cur = wxFindWindowAtPoint(p); + while (cur && cur != tb) { + last = cur; + cur = cur->GetParent(); + } + + // Focused window is not a descendant of this one + if (!cur) { + return noErr; + } + + if (last) { + result = SetElement(event, (HIObjectRef) last->GetHandle(), 0, + kEventParamAccessibleChild); + + require_noerr(result, ParameterError); + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +OSStatus wxTreebookAx::GetAllAttributeNames(wxMacCarbonEvent & event, UInt64 id) +{ + CFMutableArrayRef array; + OSStatus result; + + result = wxAccessibleMac::GetAllAttributeNames(event, id); + + require_noerr(result, ParameterError); + + result = GetArray(event, array, kEventParamAccessibleAttributeNames); + + require_noerr(result, ParameterError); + + if (!array) { + return eventNotHandledErr; + } + + CFArrayAppendValue(array, kAXContentsAttribute); + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +OSStatus wxTreebookAx::GetNamedAttribute(wxMacCarbonEvent & event, UInt64 id) +{ + wxTreebook *tb = wxDynamicCast(GetAccessible()->GetWindow(), wxTreebook); + CFMutableArrayRef array; + CFStringRef attribute; + OSStatus result; + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attribute), + &attribute); + + require_noerr(result, ParameterError); + + if (CFStringCompare(attribute, kAXChildrenAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + result = AddElement(event, (HIObjectRef) tb->GetTreeCtrl()->GetHandle(), 0, array); + + require_noerr(result, ParameterError); + + wxWindow *w = tb->GetCurrentPage(); + + if (w) { + result = AddElement(event, (HIObjectRef) w->GetHandle(), 0, array); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attribute, kAXContentsAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + result = AddElement(event, (HIObjectRef) tb->GetTreeCtrl()->GetHandle(), 0, array); + + require_noerr(result, ParameterError); + + wxWindow *w = tb->GetCurrentPage(); + + if (w) { + result = AddElement(event, (HIObjectRef) w->GetHandle(), 0, array); + + require_noerr(result, ParameterError); + } + } + else { + result = wxAccessibleMac::GetNamedAttribute(event, id); + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- + +#define IT_OUTLINE 0x0000000000000000LL +#define IT_ROW 0x0000000000000001LL +#define IT_COLUMN 0x0000000000000002LL +#define IT_ITEM 0x0000000000000003LL +#define IT_MASK 0x0000000000000003LL + +#if !defined(kAXRowExpandedNotification) +#define kAXRowExpandedNotification CFSTR("AXRowExpanded") +#endif + +#if !defined(kAXRowCollapsedNotification) +#define kAXRowCollapsedNotification CFSTR("AXRowCollapsed") +#endif + +class wxTreeCtrlAx: public wxAccessibleMac, wxEvtHandler +{ +public: + wxTreeCtrlAx(wxAccessible *acc) + : wxAccessibleMac(acc, true) + { + lastcnt = 0; + + acc->GetWindow()->Connect(wxID_ANY, + wxEVT_COMMAND_TREE_SEL_CHANGED, + wxTreeEventHandler(wxTreeCtrlAx::OnSelChanged)); + acc->GetWindow()->Connect(wxID_ANY, + wxEVT_COMMAND_TREE_ITEM_EXPANDED, + wxTreeEventHandler(wxTreeCtrlAx::OnExpanded)); + acc->GetWindow()->Connect(wxID_ANY, + wxEVT_COMMAND_TREE_ITEM_COLLAPSED, + wxTreeEventHandler(wxTreeCtrlAx::OnCollapsed)); + acc->GetWindow()->Connect(wxID_ANY, + wxEVT_IDLE, + wxIdleEventHandler(wxTreeCtrlAx::OnIdle)); + } + + virtual ~wxTreeCtrlAx() + { + } + + void OnSelChanged(wxTreeEvent & event); + void OnExpanded(wxTreeEvent & event); + void OnCollapsed(wxTreeEvent & event); + void OnIdle(wxIdleEvent & event); + + virtual OSStatus GetFocusedChild(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetChildAtPoint(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetAllAttributeNames(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus GetNamedAttribute(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus IsNamedAttributeSettable(wxMacCarbonEvent & event, UInt64 id); + virtual OSStatus SetNamedAttribute(wxMacCarbonEvent & event, UInt64 id); + + wxTreeItemId GetFirst(wxGenericTreeCtrl *tc, bool vonly); + wxTreeItemId GetNext(wxGenericTreeCtrl *tc, bool vonly, const wxTreeItemId item); + + size_t lastcnt; +}; + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +void wxTreeCtrlAx::OnExpanded(wxTreeEvent & event) +{ + wxTreeCtrl *tc = wxDynamicCast(event.GetEventObject(), wxTreeCtrl); + wxTreeItemId item = event.GetItem(); + UInt64 id = ((UInt64) item.m_pItem) | IT_ROW; + + AXNotificationHIObjectNotify(kAXRowExpandedNotification, + (HIObjectRef)tc->GetHandle(), + id); + + event.Skip(); +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +void wxTreeCtrlAx::OnCollapsed(wxTreeEvent & event) +{ + wxTreeCtrl *tc = wxDynamicCast(event.GetEventObject(), wxTreeCtrl); + wxTreeItemId item = event.GetItem(); + UInt64 id = ((UInt64) item.m_pItem) | IT_ROW; + + AXNotificationHIObjectNotify(kAXRowCollapsedNotification, + (HIObjectRef)tc->GetHandle(), + id); + + event.Skip(); +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +void wxTreeCtrlAx::OnSelChanged(wxTreeEvent & event) +{ + wxTreeCtrl *tc = wxDynamicCast(event.GetEventObject(), wxTreeCtrl); + + AXNotificationHIObjectNotify(kAXSelectedRowsChangedNotification, + (HIObjectRef)tc->GetHandle(), + 0); + + event.Skip(); +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +void wxTreeCtrlAx::OnIdle(wxIdleEvent & event) +{ + wxTreeCtrl *tc = wxDynamicCast(event.GetEventObject(), wxTreeCtrl); + + size_t cnt = 0; + wxTreeItemId item = GetFirst(tc, false); + while (item.IsOk()) { + cnt++; + item = GetNext(tc, false, item); + } + + if (cnt != lastcnt) { + AXNotificationHIObjectNotify(kAXRowCountChangedNotification, + (HIObjectRef)tc->GetHandle(), + 0); + } + lastcnt = cnt; + + event.Skip(); +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetFocusedChild event +// ---------------------------------------------------------------------------- +OSStatus wxTreeCtrlAx::GetFocusedChild(wxMacCarbonEvent & event, UInt64 id) +{ + return noErr; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetChildAtPoint event +// ---------------------------------------------------------------------------- +OSStatus wxTreeCtrlAx::GetChildAtPoint(wxMacCarbonEvent & event, UInt64 id) +{ + wxGenericTreeCtrl *tc = wxDynamicCast(GetAccessible()->GetWindow(), wxGenericTreeCtrl); + HIObjectRef objectRef = (HIObjectRef) tc->GetHandle(); + OSStatus result; + HIPoint pt; + wxPoint p; + int flags = 0; + wxTreeItemId newitem; + + wxTreeItemId item; + item.m_pItem = (wxTreeItemIdValue) (id & ~IT_MASK); + + result = event.GetParameter(kEventParamMouseLocation, + typeHIPoint, + sizeof(pt), + &pt); + if (result != noErr) { + return result; + } + + result = eventNotHandledErr; + + p.x = (int) pt.x; + p.y = (int) pt.y; + + tc->ScreenToClient(&p.x, &p.y); + + newitem = tc->HitTest(p, flags); + if (newitem.IsOk() && newitem != item) { + UInt64 id = ((UInt64)newitem.m_pItem) | IT_ITEM; + + result = SetElement(event, objectRef, id, kEventParamAccessibleChild); + + require_noerr(result, ParameterError); + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +OSStatus wxTreeCtrlAx::GetAllAttributeNames(wxMacCarbonEvent & event, UInt64 id) +{ + CFMutableArrayRef array; + OSStatus result; + + int type = id & IT_MASK; + wxTreeItemId item; + item.m_pItem = (wxTreeItemIdValue) (id & ~IT_MASK); + + result = GetArray(event, array, kEventParamAccessibleAttributeNames); + + require_noerr(result, ParameterError); + + CFArrayAppendValue(array, kAXRoleAttribute); + CFArrayAppendValue(array, kAXRoleDescriptionAttribute); + CFArrayAppendValue(array, kAXParentAttribute); + CFArrayAppendValue(array, kAXWindowAttribute); + CFArrayAppendValue(array, kAXTopLevelUIElementAttribute); + CFArrayAppendValue(array, kAXPositionAttribute); + CFArrayAppendValue(array, kAXSizeAttribute); + + switch (type) + { + case IT_OUTLINE: + { + CFArrayAppendValue(array, kAXChildrenAttribute); + CFArrayAppendValue(array, kAXHeaderAttribute); + CFArrayAppendValue(array, kAXRowsAttribute); + CFArrayAppendValue(array, kAXSelectedRowsAttribute); + CFArrayAppendValue(array, kAXVisibleRowsAttribute); + CFArrayAppendValue(array, kAXColumnsAttribute); + CFArrayAppendValue(array, kAXSelectedColumnsAttribute); + CFArrayAppendValue(array, kAXVisibleColumnsAttribute); + CFArrayAppendValue(array, kAXEnabledAttribute); + CFArrayAppendValue(array, kAXFocusedAttribute); + } + break; + + case IT_ROW: + { + CFArrayAppendValue(array, kAXSubroleAttribute); + CFArrayAppendValue(array, kAXChildrenAttribute); + CFArrayAppendValue(array, kAXVisibleChildrenAttribute); + CFArrayAppendValue(array, kAXSelectedAttribute); + CFArrayAppendValue(array, kAXIndexAttribute); + CFArrayAppendValue(array, kAXDisclosingAttribute); + CFArrayAppendValue(array, kAXDisclosedRowsAttribute); + CFArrayAppendValue(array, kAXDisclosedByRowAttribute); + CFArrayAppendValue(array, kAXDisclosureLevelAttribute); + CFArrayAppendValue(array, kAXFocusedAttribute); + } + break; + + case IT_COLUMN: + { + CFArrayAppendValue(array, kAXHeaderAttribute); + CFArrayAppendValue(array, kAXRowsAttribute); + CFArrayAppendValue(array, kAXVisibleRowsAttribute); + CFArrayAppendValue(array, kAXSelectedRowsAttribute); + CFArrayAppendValue(array, kAXIndexAttribute); + CFArrayAppendValue(array, kAXFocusedAttribute); + } + break; + + case IT_ITEM: + { + CFArrayAppendValue(array, kAXValueAttribute); + CFArrayAppendValue(array, kAXFocusedAttribute); + CFArrayAppendValue(array, kAXEnabledAttribute); + CFArrayAppendValue(array, kAXVisibleCharacterRangeAttribute); + CFArrayAppendValue(array, kAXSelectedTextAttribute); + CFArrayAppendValue(array, kAXNumberOfCharactersAttribute); + CFArrayAppendValue(array, kAXSelectedTextRangeAttribute); + } + break; + + default: + { + result = eventNotHandledErr; + } + break; + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +wxTreeItemId wxTreeCtrlAx::GetFirst(wxGenericTreeCtrl *tc, bool vonly) +{ + wxTreeItemId item = tc->GetRootItem(); + if (!item.IsOk()) { + return item; + } + + if (tc->HasFlag(wxTR_HIDE_ROOT)) { + return GetNext(tc, vonly, item); + } + + if (vonly && tc->IsVisible(item)) { + return GetNext(tc, vonly, item); + } + + return item; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +wxTreeItemId wxTreeCtrlAx::GetNext(wxGenericTreeCtrl *tc, bool vonly, const wxTreeItemId item) +{ + wxTreeItemId next; + bool isvisible; + + do { + if (tc->HasChildren(item) && tc->IsExpanded(item)) { + wxTreeItemIdValue cookie; + next = tc->GetFirstChild(item, cookie); + } + else { + wxTreeItemId parent = item; + do { + next = tc->GetNextSibling(parent); + parent = tc->GetItemParent(parent); + } while (parent.IsOk() && !(next.IsOk())); + } + + if (!next.IsOk() || !vonly) { + break; + } + + isvisible = true; + + int startX, startY; + tc->GetViewStart(&startX, &startY); + + wxSize clientSize = tc->GetClientSize(); + + wxRect rect; + if (!tc->GetBoundingRect(item, rect)) { + isvisible = false; + } + else if (rect.GetWidth() == 0 || rect.GetHeight() == 0) { + isvisible = false; + } + else if (rect.GetBottom() < 0 || rect.GetTop() > clientSize.y) { + isvisible = false; + } + else if (rect.GetRight() < 0 || rect.GetLeft() > clientSize.x) { + isvisible = false; + } + } while (vonly && !isvisible); + + return next; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +OSStatus wxTreeCtrlAx::GetNamedAttribute(wxMacCarbonEvent & event, UInt64 id) +{ + wxGenericTreeCtrl *tc = wxDynamicCast(GetAccessible()->GetWindow(), wxGenericTreeCtrl); + HIObjectRef objectRef = (HIObjectRef) tc->GetHandle(); + CFMutableArrayRef array = NULL; + CFStringRef attr; + OSStatus result; + + int type = id & IT_MASK; + wxTreeItemId item; + item.m_pItem = (wxTreeItemIdValue) (id & ~IT_MASK); + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr); + + require_noerr(result, ParameterError); + + result = eventNotHandledErr; + + if (false) + { + } + else if (CFStringCompare(attr, kAXRoleAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role; + + switch (type) + { + case IT_ROW: + role = kAXRowRole; + break; + + case IT_COLUMN: + role = kAXColumnRole; + break; + + case IT_ITEM: + role = kAXStaticTextRole; + break; + + default: + role = kAXOutlineRole; + break; + } + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(role), + &role); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXSubroleAttribute, 0) == kCFCompareEqualTo) { + if (type == IT_ROW) { + CFStringRef subrole; + + subrole = kAXOutlineRowSubrole; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(subrole), + &subrole); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXRoleDescriptionAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role = NULL; + CFStringRef subrole = NULL; + CFStringRef desc; + + switch (type) + { + case IT_OUTLINE: + role = kAXOutlineRole; + break; + + case IT_ROW: + role = kAXRowRole; + subrole = kAXOutlineRowSubrole; + break; + + case IT_COLUMN: + role = kAXColumnRole; + break; + + case IT_ITEM: + role = kAXTextAreaRole; + break; + } + + desc = HICopyAccessibilityRoleDescription(role, subrole); + if (desc) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(desc), + &desc); + + CFRelease(desc); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXParentAttribute, 0) == kCFCompareEqualTo) { + switch (type) + { + case IT_OUTLINE: + { + wxWindow *parent = tc->GetParent(); + if (parent) { + HIObjectRef objectRef = (HIObjectRef) parent->GetHandle(); + + result = SetElement(event, objectRef, 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + break; + + case IT_ROW: + { + result = SetElement(event, objectRef, 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + break; + + case IT_ITEM: + { + UInt64 id = ((UInt64)item.m_pItem) | IT_ROW; + + result = SetElement(event, objectRef, id, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + break; + } + } + else if (CFStringCompare(attr, kAXWindowAttribute, 0) == kCFCompareEqualTo) { + wxWindow *tw = wxGetTopLevelParent(tc); + + if (tw != tc) { + result = SetElement(event, (HIObjectRef) tw->GetHandle(), 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXTopLevelUIElementAttribute, 0) == kCFCompareEqualTo) { + wxWindow *tw = wxGetTopLevelParent(tc); + + if (tw != tc) { + result = SetElement(event, (HIObjectRef) tw->GetHandle(), 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXChildrenAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + switch (type) + { + case IT_OUTLINE: + { + wxTreeItemId item = GetFirst(tc, false); + while (item.IsOk()) { + UInt64 id = ((UInt64)item.m_pItem) | IT_ROW; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + + item = GetNext(tc, false, item); + } + } + break; + + case IT_ROW: + { + UInt64 id = ((UInt64)item.m_pItem) | IT_ITEM; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + } + break; + } + } + else if (CFStringCompare(attr, kAXVisibleChildrenAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + switch (type) + { + case IT_OUTLINE: + { + wxTreeItemId item = GetFirst(tc, true); + while (item.IsOk()) { + UInt64 id = ((UInt64)item.m_pItem) | IT_ROW; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + + item = GetNext(tc, true, item); + } + } + break; + + case IT_ROW: + { + UInt64 id = ((UInt64)item.m_pItem) | IT_ITEM; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + } + break; + } + } + else if (CFStringCompare(attr, kAXRowsAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + wxTreeItemId item = GetFirst(tc, false); + while (item.IsOk()) { + UInt64 id = ((UInt64)item.m_pItem) | IT_ROW; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + + item = GetNext(tc, false, item); + } + } + else if (CFStringCompare(attr, kAXSelectedRowsAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + if (tc->GetWindowStyle() & wxTR_MULTIPLE) { + wxArrayTreeItemIds items; + unsigned int cnt = tc->GetSelections(items); + + for (unsigned int i = 0; i < cnt; i++) { + UInt64 id = ((UInt64)items[i].m_pItem) | IT_ROW; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + } + } + else { + wxTreeItemId item = tc->GetSelection(); + + if (item.IsOk()) {; + UInt64 id = ((UInt64)item.m_pItem) | IT_ROW; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXVisibleRowsAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + wxTreeItemId item = GetFirst(tc, true); + while (item.IsOk()) { + UInt64 id = ((UInt64)item.m_pItem) | IT_ROW; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + + item = GetNext(tc, true, item); + } + } + else if (CFStringCompare(attr, kAXIndexAttribute, 0) == kCFCompareEqualTo) { + SInt32 index = 0; + + wxTreeItemId titem = GetFirst(tc, false); + while (titem.IsOk() && titem != item ) { + index++; + titem = GetNext(tc, false, titem); + } + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeSInt32, + sizeof(index), + &index); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXDisclosingAttribute, 0) == kCFCompareEqualTo) { + Boolean state; + + state = tc->ItemHasChildren(item) && tc->IsExpanded(item); + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXDisclosedRowsAttribute, 0) == kCFCompareEqualTo) { + wxTreeItemIdValue cookie; + + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + wxTreeItemId child = tc->GetFirstChild(item, cookie); + while (child.IsOk()) { + UInt64 id = ((UInt64)child.m_pItem) | IT_ROW; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + + child = tc->GetNextChild(item, cookie); + } + } + else if (CFStringCompare(attr, kAXDisclosedByRowAttribute, 0) == kCFCompareEqualTo) { + wxTreeItemId parent = tc->GetItemParent(item); + wxTreeItemId root = tc->GetRootItem(); + + if (parent.IsOk()) { + if (parent != root || !(tc->GetWindowStyle() & wxTR_HIDE_ROOT)) { + UInt64 id = ((UInt64)parent.m_pItem) | IT_ROW; + + result = SetElement(event, objectRef, id, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXDisclosureLevelAttribute, 0) == kCFCompareEqualTo) { + SInt32 level = 0; + wxTreeItemId parent = tc->GetItemParent(item); + + while (parent.IsOk()) { + level++; + parent = tc->GetItemParent(parent); + } + + if (tc->GetWindowStyle() & wxTR_HIDE_ROOT) { + level--; + } + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeSInt32, + sizeof(level), + &level); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXColumnsAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + UInt64 id = IT_MASK + 1 | IT_COLUMN; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXVisibleColumnsAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + UInt64 id = IT_MASK + 1 | IT_COLUMN; + + result = AddElement(event, objectRef, id, array); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXHeaderAttribute, 0) == kCFCompareEqualTo) { + result = eventNotHandledErr; + } + else if (CFStringCompare(attr, kAXSelectedColumnsAttribute, 0) == kCFCompareEqualTo) { + result = GetArray(event, array); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXValueAttribute, 0) == kCFCompareEqualTo) { + if (item.IsOk()) { + wxMacCFStringHolder holder(tc->GetItemText(item)); + const CFStringRef string = holder; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(string), + &string); + + require_noerr(result, ParameterError); + } + else { + wxASSERT_MSG(false, wxT("INVALID ITEM IN VALUE!!!!!!!!!!!!!!!!!!!!!!!\n")); + } + } + else if (CFStringCompare(attr, kAXPositionAttribute, 0) == kCFCompareEqualTo) { + wxRect wxrect = tc->GetRect(); + + switch (type) + { + case IT_OUTLINE: + case IT_COLUMN: + { + wxWindow *parent = tc->GetParent(); + if (parent) { + parent->ClientToScreen(&wxrect.x, &wxrect.y); + } + } + break; + + case IT_ROW: + { + tc->GetBoundingRect(item, wxrect); + tc->ClientToScreen(&wxrect.x, &wxrect.y); + } + break; + + case IT_ITEM: + { + tc->GetBoundingRect(item, wxrect, true); + tc->ClientToScreen(&wxrect.x, &wxrect.y); + } + break; + } + + HIPoint point = {wxrect.x, wxrect.y}; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeHIPoint, + sizeof(point), + &point); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXSizeAttribute, 0 ) == kCFCompareEqualTo) { + wxRect wxrect = tc->GetRect(); + + switch (type) + { + case IT_ROW: + { + tc->GetBoundingRect(item, wxrect); + } + break; + + case IT_ITEM: + { + tc->GetBoundingRect(item, wxrect, true); + } + break; + } + + HISize size = {wxrect.width, wxrect.height}; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeHISize, + sizeof(size), + &size); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXSelectedAttribute, 0) == kCFCompareEqualTo) { + Boolean state; + + state = tc->IsSelected(item); + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + Boolean state = false; + + if (type == IT_OUTLINE) { + state = (tc == wxWindow::FindFocus()); + } + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXEnabledAttribute, 0) == kCFCompareEqualTo) { + Boolean state; + + state = tc->IsEnabled(); + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXVisibleCharacterRangeAttribute, 0) == kCFCompareEqualTo) { + if (item.IsOk()) { + CFRange range = CFRangeMake(0, tc->GetItemText(item).Length()); + AXValueRef valRef = AXValueCreate(kAXValueCFRangeType, &range); + + if (valRef) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFTypeRef, + sizeof(valRef), + &valRef); + + CFRelease(valRef); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXNumberOfCharactersAttribute, 0) == kCFCompareEqualTo) { + if (item.IsOk()) { + CFNumberRef numRef; + int cnt = tc->GetItemText(item).Length(); + + numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &cnt); + if (numRef) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFTypeRef, + sizeof(numRef), + &numRef); + + CFRelease(numRef); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXSelectedTextRangeAttribute, 0) == kCFCompareEqualTo) { + result = noErr; + } + else if (CFStringCompare(attr, kAXSelectedTextAttribute, 0) == kCFCompareEqualTo) { + result = noErr; + } + else { + wxASSERT_MSG(false, wxT("Unhandled Attribute")); + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleIsNamedAttributeSettable event +// ---------------------------------------------------------------------------- +OSStatus wxTreeCtrlAx::IsNamedAttributeSettable(wxMacCarbonEvent & event, UInt64 id) +{ + wxGenericTreeCtrl *tc = wxDynamicCast(GetAccessible()->GetWindow(), wxGenericTreeCtrl); + OSStatus result; + CFStringRef attr; + Boolean settable = false; + + int type = id & IT_MASK; + wxTreeItemId item; + item.m_pItem = (wxTreeItemIdValue) (id & ~IT_MASK); + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFStringRef, + sizeof(attr), + &attr); + + require_noerr(result, ParameterError); + + if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + settable = true; + } + else if (CFStringCompare(attr, kAXSelectedRowsAttribute, 0) == kCFCompareEqualTo) { + if (type == IT_OUTLINE) { + settable = true; + } + } + else if (CFStringCompare(attr, kAXValueAttribute, 0) == kCFCompareEqualTo) { + if (type == IT_ITEM) { + settable = true; + } + } + else if (CFStringCompare(attr, kAXDisclosingAttribute, 0) == kCFCompareEqualTo) { + if (type == IT_ROW && tc->ItemHasChildren(item)) { + settable = true; + } + } + else if (CFStringCompare(attr, kAXSelectedAttribute, 0) == kCFCompareEqualTo) { + if (type == IT_ROW) { + settable = true; + } + } + + result = event.SetParameter(kEventParamAccessibleAttributeSettable, + typeBoolean, + sizeof(settable), + &settable); + + require_noerr(result, ParameterError); + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleSetNamedAttribute event +// ---------------------------------------------------------------------------- +OSStatus wxTreeCtrlAx::SetNamedAttribute(wxMacCarbonEvent & event, UInt64 id) +{ + wxGenericTreeCtrl *tc = wxDynamicCast(GetAccessible()->GetWindow(), wxGenericTreeCtrl); + CFStringRef attr; + OSStatus result; + + int type = id & IT_MASK; + wxTreeItemId item; + item.m_pItem = (wxTreeItemIdValue) (id & ~IT_MASK); + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFStringRef, + sizeof(attr), + &attr); + + require_noerr(result, ParameterError); + + result = eventNotHandledErr; + + if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + Boolean settable; + + result = event.GetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(settable), + &settable); + + require_noerr(result, ParameterError); + + if (settable) { + tc->SetFocus(); + + switch (type) + { + case IT_ITEM: + { + if (item.IsOk()) { + tc->SelectItem(item); + } + } + break; + } + } + } + else if (CFStringCompare(attr, kAXSelectedRowsAttribute, 0) == kCFCompareEqualTo) { + CFMutableArrayRef array; + + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + tc->UnselectAll(); + + CFIndex cnt = CFArrayGetCount(array); + for (CFIndex ndx = 0; ndx < cnt; ndx++) { + AXUIElementRef elem = (AXUIElementRef) CFArrayGetValueAtIndex(array, ndx); + if (elem) { + AXUIElementGetIdentifier(elem, &id); + + type = id & IT_MASK; + item.m_pItem = (wxTreeItemIdValue) (id & ~IT_MASK); + + if (item.IsOk()) { + tc->SelectItem(item); + } + } + } + } + else if (CFStringCompare(attr, kAXSelectedAttribute, 0) == kCFCompareEqualTo) { + Boolean state; + + result = event.GetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + + if (state && type == IT_ROW) { + if (item.IsOk()) { + tc->SelectItem(item); + } + } + } + else { + wxASSERT_MSG(false, wxT("Unhandled SetNamedAttribute()")); + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +wxAccessibleMac::wxAccessibleMac() +: m_accessible(NULL), + m_evthandlerRef(NULL), + m_roleRef(NULL), + m_subroleRef(NULL), + m_emulated(false) +{ +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +wxAccessibleMac::wxAccessibleMac(wxAccessible *acc, bool emulated) +: m_accessible(acc), + m_evthandlerRef(NULL), + m_roleRef(NULL), + m_subroleRef(NULL), + m_emulated(emulated) +{ + Init(acc, emulated); +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- +void wxAccessibleMac::Init(wxAccessible *acc, bool emulated) +{ + wxWindow *w = acc->GetWindow(); + + m_native = false; + m_roleRef = NULL; + m_subroleRef = NULL; + m_evthandlerRef = NULL; + + AXUIElementRef element = + AXUIElementCreateWithHIObjectAndIdentifier((HIObjectRef)w->GetHandle(), 0); + if (element) { + wxMacCarbonEvent event; + CFStringRef nameRef; + CFStringRef valueRef; + Boolean bypass = true; + + nameRef = kAXRoleAttribute; + valueRef = NULL; + + event.Create(kEventClassAccessibility, kEventAccessibleGetNamedAttribute); + + event.SetParameter(kEventParamBypassProbe, + typeBoolean, + sizeof(bypass), + &bypass); + event.SetParameter(kEventParamAccessibleObject, + typeCFTypeRef, + sizeof(element), + &element); + event.SetParameter(kEventParamAccessibleAttributeName, + typeCFStringRef, + sizeof(nameRef), + &nameRef); + + w->GetPeer()->SendEvent(event, 0); + + event.GetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(valueRef), + &valueRef); + + if (valueRef != NULL) { + SetDefaultRole(valueRef); + if (CFStringCompare(valueRef, kAXUnknownRole, 0) != kCFCompareEqualTo) { + if (!IsFullyEmulated()) { + SetNative(true); + } + } + CFRelease(valueRef); + } + + nameRef = kAXSubroleAttribute; + valueRef = NULL; + + w->GetPeer()->SendEvent(event, 0); + + event.GetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(valueRef), + &valueRef); + + if (valueRef != NULL) { + SetDefaultSubrole(valueRef); + CFRelease(valueRef); + } + + CFRelease(element); + } + + if (!IsNative()) { + OSStatus result; + result = InstallControlEventHandler((ControlRef)w->GetHandle(), + GetwxMacAccessibleEventHandlerUPP(), + GetEventTypeCount(eventList), + eventList, + this, + &m_evthandlerRef); + verify_noerr(result); + } + + return; +} + +wxAccessibleMac::~wxAccessibleMac() +{ + if (m_evthandlerRef != NULL) { + ::RemoveEventHandler(m_evthandlerRef); + m_evthandlerRef = NULL; + } + + if (m_roleRef) { + CFRelease(m_roleRef); + m_roleRef = NULL; + } + + if (m_subroleRef) { + CFRelease(m_subroleRef); + m_subroleRef = NULL; + } +} + +// ---------------------------------------------------------------------------- +// Deduce role +// ---------------------------------------------------------------------------- +CFStringRef wxAccessibleMac::TranslateRole(UInt64 id, CFStringRef *subrole) +{ + wxAccessible *acc = GetAccessible(); + wxWindow *w = acc->GetWindow(); + wxAccRole wxrole = wxROLE_NONE; + CFStringRef defrole; + CFStringRef defsubrole; + + *subrole = NULL; + + wxString extrole; + wxString extsubrole; + if (acc->GetExtendedRole(id, &extrole, &extsubrole) == wxACC_OK) { + wxMacCFStringHolder holder; + + if (extsubrole != wxEmptyString) { + *subrole = holder.Detach(); + } + + holder.Assign(extrole); + return holder.Detach(); + } + + defrole = GetDefaultRole(); + defsubrole = GetDefaultSubrole(); + + acc->GetRole(id, &wxrole); + + switch (wxrole) + { + case wxROLE_SYSTEM_APPLICATION: + return kAXApplicationRole; + + case wxROLE_SYSTEM_COLUMN: + return kAXColumnRole; + + case wxROLE_SYSTEM_CHECKBUTTON: + return kAXCheckBoxRole; + + case wxROLE_SYSTEM_CLIENT: + return kAXScrollAreaRole; + + case wxROLE_SYSTEM_COMBOBOX: + return kAXComboBoxRole; + + case wxROLE_SYSTEM_DIAGRAM: + return kAXImageRole; + + case wxROLE_SYSTEM_GRAPHIC: + return kAXImageRole; + + case wxROLE_SYSTEM_GROUPING: + return kAXGroupRole; + + case wxROLE_SYSTEM_HELPBALLOON: + return kAXHelpTagRole; + + case wxROLE_SYSTEM_INDICATOR: + return kAXValueIndicatorRole; + + case wxROLE_SYSTEM_LIST: + return kAXListRole; + + case wxROLE_SYSTEM_MENUBAR: + return kAXMenuBarRole; + + case wxROLE_SYSTEM_MENUITEM: + return kAXMenuItemRole; + + case wxROLE_SYSTEM_PAGETABLIST: + return kAXTabGroupRole; + + case wxROLE_SYSTEM_PANE: + return kAXScrollAreaRole; + + case wxROLE_SYSTEM_PROGRESSBAR: + return kAXProgressIndicatorRole; + + case wxROLE_SYSTEM_PUSHBUTTON: + return kAXButtonRole; + + case wxROLE_SYSTEM_RADIOBUTTON: + return kAXRadioButtonRole; + + case wxROLE_SYSTEM_ROW: + return kAXRowRole; + + case wxROLE_SYSTEM_SCROLLBAR: + return kAXScrollBarRole; + + case wxROLE_SYSTEM_SLIDER: + return kAXSliderRole; + + case wxROLE_SYSTEM_SPINBUTTON: + return kAXIncrementorRole; + + case wxROLE_SYSTEM_STATICTEXT: + return kAXStaticTextRole; + + case wxROLE_SYSTEM_TABLE: + return kAXTableRole; + + case wxROLE_SYSTEM_TEXT: + return kAXTextAreaRole; + + case wxROLE_SYSTEM_TOOLBAR: + return kAXToolbarRole; + + case wxROLE_SYSTEM_TOOLTIP: + return kAXHelpTagRole; + + case wxROLE_SYSTEM_WINDOW: + return kAXWindowRole; + + default: + break; + } + + defrole = GetDefaultRole(); + defsubrole = GetDefaultSubrole(); + + if (defrole && CFStringCompare(defrole, kAXUnknownRole, 0) != kCFCompareEqualTo) { + if (defsubrole && CFStringCompare(defrole, kAXUnknownRole, 0) != kCFCompareEqualTo) { + *subrole = defsubrole; + } + return defrole; + } + + if (wxIsKindOf(w, wxPanel)) { + CFSTR("Panel"); + } + + if (wxIsKindOf(w, wxStaticBitmap)) { + return kAXImageRole; + } + + if (wxIsKindOf(w, wxStatusBar)) { + return kAXGroupRole; + } + + if (wxIsKindOf(w, wxGenericTreeCtrl)) { + return kAXOutlineRole; + } + + if (wxIsKindOf(w, wxTreebook)) { + return kAXScrollAreaRole; + } + + if (wxIsKindOf(w, wxWindow)) { + return kAXScrollAreaRole; + } + + wxASSERT_MSG(false, wxT("Unknown Role")); + + return kAXUnknownRole; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetChildAtPoint event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::GetChildAtPoint(wxMacCarbonEvent & event, UInt64 id) +{ + wxAccessible *acc = GetAccessible(); + wxWindow *w = acc->GetWindow(); + OSStatus result; + wxAccStatus st; + int cnt = 0; + HIPoint pt; + + result = event.GetParameter(kEventParamMouseLocation, + typeHIPoint, + sizeof(pt), + &pt); + + require_noerr(result, ParameterError); + + result = eventNotHandledErr; + + if (id > 0) { + wxAccessible *cacc; + st = acc->GetChild(id, &cacc); + if (st != wxACC_OK || cacc == NULL || cacc == acc) { + return eventNotHandledErr; + } + acc = cacc; + w = acc->GetWindow(); + id = 0; + } + + st = acc->GetChildCount(&cnt); + if (st == wxACC_OK && cnt > 0) { + int id = -1; + + // Scan backwards to avoid stopping on a wxStaticBox instead + // of the windows "within" it. + for (int i = cnt; i >= 1; i--) { + wxRect rect; + if (acc->GetLocation(rect, i) == wxACC_OK) { + + if (rect.Contains((int) pt.x, (int) pt.y)) { + wxAccessible *cacc; + cacc = NULL; + acc->GetChild(i, &cacc); + + if (cacc) { + w = cacc->GetWindow(); + id = 0; + } + else { + id = i; + } + break; + } + } + } + + if (id >= 0) { + result = SetElement(event, (HIObjectRef) w->GetHandle(), id, + kEventParamAccessibleChild); + + require_noerr(result, ParameterError); + } + else { + return eventNotHandledErr; + } + } + else { + return eventNotHandledErr; + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetFocusedChild event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::GetFocusedChild(wxMacCarbonEvent & event, UInt64 id) +{ + wxAccessible *acc = GetAccessible(); + wxWindow *w = acc->GetWindow(); + OSStatus result = eventNotHandledErr; + wxAccessible *cacc = NULL; + int childId = 0; + wxAccStatus st; + int cnt; + + if (id > 0) { + st = acc->GetChild(id, &cacc); + if (st != wxACC_OK || cacc == NULL || cacc == acc) { + return noErr; + } + acc = cacc; + cacc = NULL; + w = acc->GetWindow(); + id = 0; + } + + st = acc->GetFocus(&childId, &cacc); + if (st == wxACC_FAIL) { + return result; + } + + if (st == wxACC_OK) { + if (cacc == acc) { + return noErr; + } + + if (cacc) { + result = SetElement(event, (HIObjectRef) cacc->GetWindow()->GetHandle(), 0, + kEventParamAccessibleChild); + + return result; + } + + if (childId == wxACC_SELF) { + return noErr; + } + + result = SetElement(event, (HIObjectRef) w->GetHandle(), childId, + kEventParamAccessibleChild); + + return result; + } + + wxWindow *focused = wxWindow::FindFocus(); + wxWindow *last; + wxWindow *cur; + + if (!focused) { + return result; + } + + last = NULL; + cur = focused; + while (cur && cur != w) { + last = cur; + cur = cur->GetParent(); + } + + // Focused window is not a descendant of this one + if (!cur) { + return noErr; + } + + // Focused window is a descendant so return immediate child + if (last != NULL) { + result = SetElement(event, (HIObjectRef) last->GetHandle(), 0, + kEventParamAccessibleChild); + + require_noerr(result, ParameterError); + + return result; + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetAllAttributeNames event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::GetAllAttributeNames(wxMacCarbonEvent & event, UInt64 id) +{ + wxAccessible *acc = GetAccessible(); + OSStatus result; + wxAccStatus st; + wxString wxvalue; + + CFMutableArrayRef array; + + result = GetArray(event, array, kEventParamAccessibleAttributeNames); + + require_noerr(result, ParameterError); + + CFStringRef role; + CFStringRef subrole; + + role = TranslateRole(id, &subrole); + + CFArrayAppendValue(array, kAXRoleAttribute); + + if (subrole) { + CFArrayAppendValue(array, kAXSubroleAttribute); + } + + CFArrayAppendValue(array, kAXRoleDescriptionAttribute); + CFArrayAppendValue(array, kAXParentAttribute); + CFArrayAppendValue(array, kAXWindowAttribute); + CFArrayAppendValue(array, kAXTopLevelUIElementAttribute); + CFArrayAppendValue(array, kAXPositionAttribute); + CFArrayAppendValue(array, kAXSizeAttribute); + CFArrayAppendValue(array, kAXEnabledAttribute); + CFArrayAppendValue(array, kAXFocusedAttribute); + + if (id == 0) { + CFArrayAppendValue(array, kAXChildrenAttribute); +// CFArrayAppendValue(array, kAXSelectedChildrenAttribute); +// CFArrayAppendValue(array, kAXVisibleChildrenAttribute); + CFArrayAppendValue(array, kAXContentsAttribute); + } + + CFArrayAppendValue(array, kAXTitleAttribute); + CFArrayAppendValue(array, kAXHelpAttribute); + CFArrayAppendValue(array, kAXDescriptionAttribute); + + if (CFStringCompare(role, kAXSliderRole, 0) == kCFCompareEqualTo) { + CFArrayAppendValue(array, kAXValueAttribute); + CFArrayAppendValue(array, kAXMinValueAttribute); + CFArrayAppendValue(array, kAXMaxValueAttribute); + return result; + } + + if (CFStringCompare(role, kAXTextAreaRole, 0) == kCFCompareEqualTo) { + CFArrayAppendValue(array, kAXValueAttribute); + return result; + } + + st = acc->GetValue(id, &wxvalue); + if (st == wxACC_OK) { + CFArrayAppendValue(array, kAXValueAttribute); + } + +// CFShow(array); +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetAllParameterizedAttributeNames event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::GetAllParameterizedAttributeNames(wxMacCarbonEvent & event, UInt64 id) +{ + return eventNotHandledErr; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetNamedAttribute event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::GetNamedAttribute(wxMacCarbonEvent & event, UInt64 id) +{ + wxAccessible *acc = GetAccessible(); + wxWindow *w = acc->GetWindow(); + OSStatus result; + wxAccStatus st; + CFStringRef attr; + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFStringRef, + sizeof(attr), + &attr); + + require_noerr(result, ParameterError); + + result = eventNotHandledErr; + + if (CFStringCompare(attr, kAXChildrenAttribute, 0) == kCFCompareEqualTo) { + CFMutableArrayRef array; + int cnt = 0; + + // Current element/identifier will not have any children as it + // would have already been resolved in the event handler. + if (id != 0) { + return noErr; + } + + st = acc->GetChildCount(&cnt); + if (st != wxACC_OK || cnt == 0) { + return eventNotHandledErr; + } + + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + for (int i = 1; i <= cnt; i++) { + wxAccessible *cacc; + wxWindow *cw; + bool shown; + long wxstate; + int id; + + cacc = NULL; + acc->GetChild(i, &cacc); + if (cacc) { + cw = cacc->GetWindow(); + id = 0; + } + else { + cw = w; + id = i; + } + + if (!cw->IsTopLevel()) { + wxstate = 0; + st = acc->GetState(id, &wxstate); + if (st == wxACC_OK) { + if (wxstate & wxACC_STATE_SYSTEM_INVISIBLE) { + shown = false; + } + else { + shown = cw->IsShown(); + } + } + else { + shown = cw->IsShown(); + } + + if (shown) { + result = AddElement(event, (HIObjectRef)cw->GetHandle(), id, array); + + require_noerr(result, ParameterError); + } + } + } + + result = noErr; + } + else if (CFStringCompare(attr, kAXVisibleChildrenAttribute, 0) == kCFCompareEqualTo) { + CFMutableArrayRef array; + int cnt = 0; + + // Current element/identifier will not have any children as it + // would have already been resolved above. + if (id != 0) { + return noErr; + } + + st = acc->GetChildCount(&cnt); + if (st != wxACC_OK || cnt == 0) { + return eventNotHandledErr; + } + + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + for (int i = 1; i <= cnt; i++) { + wxAccessible *cacc; + wxWindow *cw; + bool shown; + long wxstate; + int id; + + cacc = NULL; + acc->GetChild(i, &cacc); + if (cacc) { + cw = cacc->GetWindow(); + id = 0; + } + else { + cw = w; + id = i; + } + + wxstate = 0; + st = acc->GetState(id, &wxstate); + if (st == wxACC_OK) { + if (wxstate & wxACC_STATE_SYSTEM_INVISIBLE) { + shown = false; + } + else { + shown = cw->IsShown(); + } + } + else { + shown = cw->IsShown(); + } + + if (shown) { + result = AddElement(event, (HIObjectRef)cw->GetHandle(), id, array); + + require_noerr(result, ParameterError); + } + } + + result = noErr; + } + else if (CFStringCompare(attr, kAXSelectedChildrenAttribute, 0) == kCFCompareEqualTo) { + CFMutableArrayRef array; + int cnt = 0; + + // Current element/identifier will not have any children as it + // would have already been resolved above. + if (id != 0) { + return noErr; + } + + st = acc->GetChildCount(&cnt); + if (st != wxACC_OK || cnt == 0) { + return eventNotHandledErr; + } + + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + for (int i = 1; i <= cnt; i++) { + wxAccessible *cacc; + wxWindow *cw; + bool selected; + long wxstate; + int id; + + cacc = NULL; + acc->GetChild(i, &cacc); + if (cacc) { + cw = cacc->GetWindow(); + id = 0; + } + else { + cw = w; + id = i; + } + + wxstate = 0; + st = acc->GetState(id, &wxstate); + if (st == wxACC_OK && wxstate & wxACC_STATE_SYSTEM_SELECTED) { + selected = true; + } + else { + selected = false; + } + + if (selected) { + result = AddElement(event, (HIObjectRef)cw->GetHandle(), id, array); + + require_noerr(result, ParameterError); + } + } + + result = noErr; + } + else if (CFStringCompare(attr, kAXContentsAttribute, 0) == kCFCompareEqualTo) { + CFMutableArrayRef array; + int cnt = 0; + + // Current element/identifier will not have any children as it + // would have already been resolved above. + if (id != 0) { + return noErr; + } + + st = acc->GetChildCount(&cnt); + if (st != wxACC_OK || cnt == 0) { + return eventNotHandledErr; + } + + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + for (int i = 1; i <= cnt; i++) { + wxAccessible *cacc; + wxWindow *cw; + bool shown; + long wxstate; + int id; + + cacc = NULL; + acc->GetChild(i, &cacc); + if (cacc) { + cw = cacc->GetWindow(); + id = 0; + } + else { + cw = w; + id = i; + } + + wxstate = 0; + st = acc->GetState(id, &wxstate); + if (st == wxACC_OK) { + if (wxstate & wxACC_STATE_SYSTEM_INVISIBLE) { + shown = false; + } + else { + shown = cw->IsShown(); + } + } + else { + shown = cw->IsShown(); + } + + if (shown) { + result = AddElement(event, (HIObjectRef)cw->GetHandle(), id, array); + + require_noerr(result, ParameterError); + } + } + + result = noErr; + } + else if (CFStringCompare(attr, kAXWindowAttribute, 0) == kCFCompareEqualTo) { + wxWindow *tw = wxGetTopLevelParent(w); + + if (tw != w) { + result = SetElement(event, (HIObjectRef) tw->GetHandle(), 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXTopLevelUIElementAttribute, 0) == kCFCompareEqualTo) { + wxWindow *tw = wxGetTopLevelParent(w); + + if (tw != w) { + result = SetElement(event, (HIObjectRef) tw->GetHandle(), 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXParentAttribute, 0) == kCFCompareEqualTo) { + wxWindow *parent; + + if (id == 0) { + wxAccessible *pacc = NULL; + st = acc->GetParent(&pacc); + if (st != wxACC_OK || pacc == NULL || pacc == acc) { + parent = w->GetParent(); + } + else { + parent = pacc->GetWindow(); + } + } + else { + parent = w; + } + + if (parent) { + HIObjectRef objectRef; + + if (w->IsTopLevel()) { + objectRef = (HIObjectRef)HIViewGetRoot((WindowRef)w->MacGetTopLevelWindowRef()); + } + else { + objectRef = (HIObjectRef) parent->GetHandle(); + } + + result = SetElement(event, objectRef, 0, + kEventParamAccessibleAttributeValue); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXRoleAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role; + CFStringRef subrole; + + role = TranslateRole(id, &subrole); + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(role), + &role); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXSubroleAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role; + CFStringRef subrole; + + role = TranslateRole(id, &subrole); + if (subrole) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(subrole), + &subrole); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXRoleDescriptionAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role; + CFStringRef subrole; + CFStringRef desc; + + role = TranslateRole(id, &subrole); + + desc = HICopyAccessibilityRoleDescription(role, subrole); + if (desc) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(desc), + &desc); + + CFRelease(desc); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXTitleAttribute, 0) == kCFCompareEqualTo) { + wxString wxtitle; + + st = acc->GetName(id, &wxtitle); + if (st == wxACC_OK) { + wxMacCFStringHolder holder(wxtitle); + const CFStringRef title = holder; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(title), + &title); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXDescriptionAttribute, 0) == kCFCompareEqualTo) { + wxString wxdesc; + + st = acc->GetDescription(id, &wxdesc); + if (st == wxACC_OK) { + + wxMacCFStringHolder holder(wxdesc); + const CFStringRef desc = holder; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(desc), + &desc); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXHelpAttribute, 0) == kCFCompareEqualTo) { + wxString wxhelp; + + st = acc->GetHelpText(id, &wxhelp); + if (st != wxACC_OK || wxhelp.IsEmpty()) { +#if wxUSE_TOOLTIPS + wxToolTip *tip = w->GetToolTip(); + if (tip) { + wxhelp = tip->GetTip(); + } +#endif + } + + if (!wxhelp.IsEmpty()) { + wxMacCFStringHolder holder(wxhelp); + const CFStringRef help = holder; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(help), + &help); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXValueAttribute, 0) == kCFCompareEqualTo) { + wxString wxvalue; + + st = acc->GetValue(id, &wxvalue); + if (st == wxACC_OK) { + CFStringRef role; + CFStringRef subrole; + + role = TranslateRole(id, &subrole); + + if (CFStringCompare(role, kAXSliderRole, 0) == kCFCompareEqualTo) { + CFNumberRef numRef; + double val = 0; + + wxvalue.ToDouble(&val); + + numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &val); + if (numRef) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFTypeRef, + sizeof(numRef), + &numRef); + + CFRelease(numRef); + + require_noerr(result, ParameterError); + } + } + else { + wxMacCFStringHolder holder(wxvalue); + const CFStringRef value = holder; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(value), + &value); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXMinValueAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role; + CFStringRef subrole; + + role = TranslateRole(id, &subrole); + + if (CFStringCompare(role, kAXSliderRole, 0) == kCFCompareEqualTo) { + CFNumberRef numRef; + double val = 0; + + numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &val); + if (numRef) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFTypeRef, + sizeof(numRef), + &numRef); + + CFRelease(numRef); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXMaxValueAttribute, 0) == kCFCompareEqualTo) { + CFStringRef role; + CFStringRef subrole; + + role = TranslateRole(id, &subrole); + + if (CFStringCompare(role, kAXSliderRole, 0) == kCFCompareEqualTo) { + CFNumberRef numRef; + double val = 100; + + numRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &val); + if (numRef) { + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFTypeRef, + sizeof(numRef), + &numRef); + + CFRelease(numRef); + + require_noerr(result, ParameterError); + } + } + } + else if (CFStringCompare(attr, kAXEnabledAttribute, 0) == kCFCompareEqualTo) { + long wxstate = 0; + Boolean state = true; + + st = acc->GetState(id, &wxstate); + + if (wxstate & wxACC_STATE_SYSTEM_UNAVAILABLE) { + state = false; + } + else { + state = w->IsEnabled(); + if (!w->IsShown()) { + state = false; + } + } + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + long wxstate = 0; + Boolean state; + + st = acc->GetState(id, &wxstate); + if (st == wxACC_OK) { + state = (wxstate & wxACC_STATE_SYSTEM_FOCUSED ? true : false); + } + else { + state = (w == wxWindow::FindFocus()); + } + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(state), + &state); + + require_noerr(result, ParameterError); + } + else if (CFStringCompare(attr, kAXPositionAttribute, 0) == kCFCompareEqualTo) { + wxRect wxrect; + + st = acc->GetLocation(wxrect, id); + if (st == wxACC_OK) { + HIPoint point = {wxrect.x, wxrect.y}; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeHIPoint, + sizeof(point), + &point); + + require_noerr(result, ParameterError); + } + } + else if (CFStringCompare(attr, kAXSizeAttribute, 0 ) == kCFCompareEqualTo) { + wxRect wxrect; + + st = acc->GetLocation(wxrect, id); + if (st == wxACC_OK) { + HISize size = {wxrect.width, wxrect.height}; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeHISize, + sizeof(size), + &size); + + require_noerr(result, ParameterError); + } + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleIsNamedAttributeSettable event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::IsNamedAttributeSettable(wxMacCarbonEvent & event, UInt64 id) +{ + OSStatus result; + CFStringRef attr; + Boolean settable = false; + wxAccessible *acc = NULL; + wxWindow *w = NULL; + + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFStringRef, + sizeof(attr), + &attr); + + require_noerr(result, ParameterError); + + acc = GetAccessible(); + w = acc->GetWindow(); + + if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + settable = true; + } + else if (CFStringCompare(attr, kAXSelectedChildrenAttribute, 0) == kCFCompareEqualTo) { + settable = true; + } + + result = event.SetParameter(kEventParamAccessibleAttributeSettable, + typeBoolean, + sizeof(settable), + &settable); + + require_noerr(result, ParameterError); + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleSetNamedAttribute event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::SetNamedAttribute(wxMacCarbonEvent & event, UInt64 id) +{ + wxAccessible *acc = GetAccessible(); + wxWindow *w = acc->GetWindow(); + OSStatus result; + CFStringRef attr; + Boolean settable; + result = event.GetParameter(kEventParamAccessibleAttributeName, + typeCFStringRef, + sizeof(attr), + &attr); + + require_noerr(result, ParameterError); + + result = eventNotHandledErr; + + if (CFStringCompare(attr, kAXFocusedAttribute, 0) == kCFCompareEqualTo) { + result = event.GetParameter(kEventParamAccessibleAttributeValue, + typeBoolean, + sizeof(settable), + &settable); + + require_noerr(result, ParameterError); + + if (settable) { + w->SetFocus(); + wxAccStatus st = acc->Select(id, wxACC_SEL_TAKEFOCUS); + if (st != wxACC_OK) { + result = eventNotHandledErr; + } + } + } + else if (CFStringCompare(attr, kAXSelectedChildrenAttribute, 0) == kCFCompareEqualTo) { + CFMutableArrayRef array; + + result = GetArray(event, array); + + require_noerr(result, ParameterError); + + wxAccSelectionFlags wxstate = wxACC_SEL_TAKESELECTION; + + CFIndex cnt = CFArrayGetCount(array); + for (CFIndex ndx = 0; ndx < cnt; ndx++) { + AXUIElementRef elem = (AXUIElementRef) CFArrayGetValueAtIndex(array, ndx); + if (elem) { + AXUIElementGetIdentifier(elem, &id); + + wxAccStatus st = acc->Select(id, wxstate); + if (st != wxACC_OK) { + result = eventNotHandledErr; + break; + } + + wxstate = wxACC_SEL_ADDSELECTION; + } + } + } + else { + wxASSERT_MSG(false, wxT("Unhandled SetNamedAttribute()")); + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetAllActionNames event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::GetAllActionNames(wxMacCarbonEvent & event, UInt64 id) +{ + wxAccessible *acc = GetAccessible(); + OSStatus result; + wxAccStatus st; + CFMutableArrayRef array; + wxString wxaction; + + result = GetArray(event, array, kEventParamAccessibleActionNames); + + require_noerr(result, ParameterError); + + CFStringRef role; + CFStringRef subrole; + role = TranslateRole(id, &subrole); + + CFArrayAppendValue(array, kAXShowMenuAction); + + st = acc->GetDefaultAction(id, &wxaction); + if (st == wxACC_OK && !wxaction.IsEmpty()) { + if (CFStringCompare(role, kAXButtonRole, 0) == kCFCompareEqualTo) { + if (wxaction.CmpNoCase(wxT("Press")) == 0) { + CFArrayAppendValue(array, kAXPressAction); + return noErr; + } + } + + wxMacCFStringHolder action(wxaction); + CFArrayAppendValue(array, action); + return noErr; + } + + if (CFStringCompare(role, kAXButtonRole, 0) == kCFCompareEqualTo) { + CFArrayAppendValue(array, kAXPressAction); + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessibleGetNamedActionDescription event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::GetNamedActionDescription(wxMacCarbonEvent & event, UInt64 id) +{ + OSStatus result; + CFStringRef action; + CFMutableStringRef desc; + CFStringRef sysdesc; + + result = event.GetParameter(kEventParamAccessibleActionName, + typeCFStringRef, + sizeof(action), + &action); + + require_noerr(result, ParameterError); + + result = event.GetParameter(kEventParamAccessibleActionDescription, + typeCFMutableStringRef, + sizeof(desc), + &desc); + + require_noerr(result, ParameterError); + + sysdesc = HICopyAccessibilityActionDescription(action); + if (sysdesc) { + CFStringReplaceAll(desc, sysdesc); + CFRelease(sysdesc); + } + +ParameterError: + return result; +} + +// ---------------------------------------------------------------------------- +// Handle the kEventAccessiblePerformNamedAction event +// ---------------------------------------------------------------------------- +OSStatus wxAccessibleMac::PerformNamedAction(wxMacCarbonEvent & event, UInt64 id) +{ + wxAccessible *acc = GetAccessible(); + wxWindow *w = acc->GetWindow(); + OSStatus result = eventNotHandledErr; + CFStringRef action; + wxAccStatus st; + wxString wxaction; + CFStringRef role; + CFStringRef subrole; + + result = event.GetParameter(kEventParamAccessibleActionName, + typeCFStringRef, + sizeof(action), + &action); + + require_noerr(result, ParameterError); + + result = eventNotHandledErr; + + if (CFStringCompare(action, kAXShowMenuAction, 0) == kCFCompareEqualTo) { + wxContextMenuEvent evt(wxEVT_CONTEXT_MENU, + w->GetId(), + w->ClientToScreen(w->GetPosition())); + evt.SetEventObject(w); + w->GetEventHandler()->ProcessEvent(evt); + return noErr; + } + + st = acc->GetDefaultAction(id, &wxaction); + if (st == wxACC_OK && !wxaction.IsEmpty()) { + wxMacCFStringHolder holder(wxaction); + if (CFStringCompare(action, kAXPressAction, 0) == kCFCompareEqualTo) { + action = CFSTR("Press"); + } + + if (CFStringCompare(action, holder, 0) == kCFCompareEqualTo) { + acc->DoDefaultAction(id); + return noErr; + } + } + + role = TranslateRole(id, &subrole); + + if (CFStringCompare(role, kAXButtonRole, 0) == kCFCompareEqualTo) { + if (CFStringCompare(action, kAXPressAction, 0) == kCFCompareEqualTo) { + HIViewSimulateClick((ControlRef) w->GetHandle(), (HIViewPartCode)0, 0, NULL); + return noErr; + } + } + +ParameterError: + return result; +} + +CFStringRef wxAccessibleMac::GetDefaultRole() +{ + return m_roleRef; +} + +void wxAccessibleMac::SetDefaultRole(const CFStringRef role) +{ + if (m_roleRef) { + CFRelease(m_roleRef); + m_roleRef = NULL; + } + + if (role && CFStringCompare(role, kAXUnknownRole, 0) != kCFCompareEqualTo) { + m_roleRef = CFStringCreateCopy(NULL, role); + } +} + +bool wxAccessibleMac::HasDefaultRole() +{ + return m_roleRef != NULL; +} + +CFStringRef wxAccessibleMac::GetDefaultSubrole() +{ + return m_subroleRef; +} + +void wxAccessibleMac::SetDefaultSubrole(const CFStringRef subrole) +{ + if (m_subroleRef) { + CFRelease(m_subroleRef); + m_subroleRef = NULL; + } + + if (subrole && CFStringCompare(subrole, kAXUnknownRole, 0) != kCFCompareEqualTo) { + m_subroleRef = CFStringCreateCopy(NULL, subrole); + } +} + +bool wxAccessibleMac::HasDefaultSubrole() +{ + return m_subroleRef != NULL; +} + +void wxAccessibleMac::SetNative(bool native) +{ + m_native = native; +} + +bool wxAccessibleMac::IsNative() +{ + return m_native; +} + +// ---------------------------------------------------------------------------- +// +// ---------------------------------------------------------------------------- + +static pascal OSStatus wxMacAccessibleDescEventHandler(EventHandlerCallRef handlerRef, EventRef eventRef, void *data) +{ + wxMacCarbonEvent event(eventRef); + wxWindow *w = wxDynamicCast(data, wxWindow); + OSStatus result = CallNextEventHandler(handlerRef, eventRef); + + switch (event.GetKind()) + { + case kEventAccessibleGetAllAttributeNames: + { + CFMutableArrayRef array; + + require_noerr(GetArray(event, array, kEventParamAccessibleAttributeNames), + ParameterError); + + bool dfound = false; +#if wxUSE_TOOLTIPS + bool hfound = false; +#endif + + CFIndex cnt = CFArrayGetCount(array); + for (CFIndex ndx = 0; ndx < cnt; ndx++) { + CFStringRef val = (CFStringRef) CFArrayGetValueAtIndex(array, ndx); + if (CFStringCompare(val, kAXDescriptionAttribute, 0) == kCFCompareEqualTo) { + dfound = true; + } +#if wxUSE_TOOLTIPS + if (CFStringCompare(val, kAXHelpAttribute, 0) == kCFCompareEqualTo) { + hfound = true; + } +#endif + } + + if (!dfound) { + CFArrayAppendValue(array, kAXDescriptionAttribute); + result = noErr; + } +#if wxUSE_TOOLTIPS + if (!hfound) { + CFArrayAppendValue(array, kAXHelpAttribute); + result = noErr; + } +#endif + } + break; + + case kEventAccessibleGetNamedAttribute: + { + CFStringRef attr; + + require_noerr(event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr), ParameterError); + + if (CFStringCompare(attr, kAXDescriptionAttribute, 0) == kCFCompareEqualTo) { + CFStringRef desc; + + if (event.GetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(desc), + &desc) == noErr) { + break; + } + + wxWindow *s = w->GetPrevSibling(); + bool use = false; + + if (s && wxIsKindOf(s, wxStaticText)) { + wxRect wr = w->GetRect(); + wxRect sr = s->GetRect(); + + if ((sr.GetTop() >= wr.GetTop() && sr.GetTop() <= wr.GetBottom()) || + (sr.GetBottom() >= wr.GetTop() && sr.GetBottom() <= wr.GetBottom())) { + use = true; + w = s; + } + } + else { + s = w->GetParent(); + if (wxIsKindOf(s, wxComboBox)) { + use = true; + w = s; + } + } + + wxString wxdesc = w->GetLabel(); + if (wxdesc.IsEmpty()) { + wxdesc = w->GetName(); + } + + wxdesc = wxStripMenuCodes(wxdesc, wxStrip_All); + + if (!wxdesc.IsEmpty()) { + wxMacCFStringHolder holder(wxdesc); + desc = holder; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(desc), + &desc); + + require_noerr(result, ParameterError); + } + } +#if wxUSE_TOOLTIPS + else if (CFStringCompare(attr, kAXHelpAttribute, 0) == kCFCompareEqualTo) { + CFStringRef help; + + if (event.GetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(help), + &help) == noErr) { + break; + } + + wxString wxhelp; + wxToolTip *tip = w->GetToolTip(); + if (tip) { + wxhelp = tip->GetTip(); + } + + if (!wxhelp.IsEmpty()) { + wxMacCFStringHolder holder(wxhelp); + help = holder; + + result = event.SetParameter(kEventParamAccessibleAttributeValue, + typeCFStringRef, + sizeof(help), + &help); + + require_noerr(result, ParameterError); + } + } +#endif + } + break; + + case kEventAccessibleIsNamedAttributeSettable: + { + CFStringRef attr; + Boolean settable = false; + + require_noerr(event.GetParameter(kEventParamAccessibleAttributeName, + typeCFTypeRef, + sizeof(attr), + &attr), ParameterError); + + result = event.SetParameter(kEventParamAccessibleAttributeSettable, + typeBoolean, + sizeof(settable), + &settable); + + require_noerr(result, ParameterError); + } + break; + } + +ParameterError: + return result; +} + +DEFINE_ONE_SHOT_HANDLER_GETTER(wxMacAccessibleDescEventHandler); + +static void InstallDescriptionHandler(wxWindow *w) +{ + ControlRef obj = (ControlRef) w->GetHandle(); + EventTargetRef target = GetControlEventTarget(obj); + + if (wxIsKindOf(w, wxTextCtrl)) { + HIViewRef view = HIViewGetFirstSubview((HIViewRef) obj); + while (view) { + if (HIObjectIsOfClass((HIObjectRef) view, kHITextViewClassID)) { + break; + } + view = HIViewGetNextView(view); + } + + if (view) { + TXNObject txn = HITextViewGetTXNObject(view); + if (txn) { + HIObjectRef obj = NULL; + TXNGetAccessibilityHIObject(txn, &obj); + InstallEventHandler(HIObjectGetEventTarget(obj), + GetwxMacAccessibleDescEventHandlerUPP(), + GetEventTypeCount(namedAttrsList), + namedAttrsList, + w, + NULL); + } + } + } + + if (target) { + InstallEventHandler(target, + GetwxMacAccessibleDescEventHandlerUPP(), + GetEventTypeCount(namedAttrsList), + namedAttrsList, + w, + NULL); + } + + return; +} + +// ---------------------------------------------------------------------------- +// wxAccessible implementation +// ---------------------------------------------------------------------------- + +// ctors + +wxAccessible::wxAccessible(wxWindow *win) +: wxAccessibleBase(win), + m_accessiblemac(NULL) +{ + Init(); +} + +// common part of all ctors +void wxAccessible::Init() +{ + wxWindow *w = GetWindow(); + + InstallDescriptionHandler(w); + + if (0) { + } + else if (wxIsKindOf(w, wxTextCtrl)) { + m_accessiblemac = new wxTextCtrlAx(this); + } + else if (wxIsKindOf(w, wxTreebook)) { + m_accessiblemac = new wxTreebookAx(this); + } + else if (wxIsKindOf(w, wxGenericTreeCtrl)) { + m_accessiblemac = new wxTreeCtrlAx(this); + } + else if (wxIsKindOf(w, wxSlider)) { + m_accessiblemac = new wxSliderAx(this); + } +/* + else if (wxIsKindOf(w, wxDatePickerCtrl)) { + m_accessiblemac = new wxDatePickerCtrlAx(this); + } +*/ + else if (wxIsKindOf(w, wxListCtrl)) { + m_accessiblemac = new wxListCtrlAx(this); + } + else { + m_accessiblemac = new wxAccessibleMac(this); + } +} + +wxAccessible::~wxAccessible() +{ + if (m_accessiblemac) { + delete m_accessiblemac; + m_accessiblemac = NULL; + } +} + +wxAccStatus wxAccessible::GetExtendedRole(int childId, wxString *role, wxString *subrole) +{ + *role = wxEmptyString; + *subrole = wxEmptyString; + + return wxACC_NOT_IMPLEMENTED; +} + +// Sends an event when something changes in an accessible object. +void wxAccessible::NotifyEvent(int eventType, wxWindow* window, wxAccObject objectType, int objectId) +{ + switch (eventType) + { + case wxACC_EVENT_OBJECT_FOCUS: + { + AXNotificationHIObjectNotify(kAXFocusedUIElementChangedNotification, + (HIObjectRef)window->GetHandle(), + objectId); + } + break; + + case wxACC_EVENT_OBJECT_SELECTIONREMOVE: + { + AXNotificationHIObjectNotify(kAXSelectedChildrenChangedNotification, + (HIObjectRef)window->GetHandle(), + 0); + } + break; + + case wxACC_EVENT_OBJECT_SELECTION: + { + AXNotificationHIObjectNotify(kAXSelectedChildrenChangedNotification, + (HIObjectRef)window->GetHandle(), + 0); + } + break; + + case wxACC_EVENT_OBJECT_NAMECHANGE: + case wxACC_EVENT_OBJECT_VALUECHANGE: + { + AXNotificationHIObjectNotify(kAXValueChangedNotification, + (HIObjectRef)window->GetHandle(), + objectId); + } + break; + } +} + +#endif // wxUSE_OLE && wxUSE_ACCESSIBILITY diff -ruN orig/wxMac-2.8.12/src/mac/carbon/graphics.cpp wxMac-2.8.12/src/mac/carbon/graphics.cpp --- orig/wxMac-2.8.12/src/mac/carbon/graphics.cpp 2011-03-22 07:34:35.000000000 -0500 +++ wxMac-2.8.12/src/mac/carbon/graphics.cpp 2015-04-21 12:14:01.000000000 -0500 @@ -1069,7 +1069,7 @@ virtual void Transform( const wxGraphicsMatrixData* matrix ); // gets the bounding box enclosing all points (possibly including control points) - virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *y) const; + virtual void GetBox(wxDouble *x, wxDouble *y, wxDouble *w, wxDouble *h) const; virtual bool Contains( wxDouble x, wxDouble y, int fillStyle = wxODDEVEN_RULE) const; private : diff -ruN orig/wxMac-2.8.12/src/mac/carbon/window.cpp wxMac-2.8.12/src/mac/carbon/window.cpp --- orig/wxMac-2.8.12/src/mac/carbon/window.cpp 2011-03-22 07:34:36.000000000 -0500 +++ wxMac-2.8.12/src/mac/carbon/window.cpp 2015-04-21 11:05:15.000000000 -0500 @@ -1229,6 +1229,10 @@ SetInitialSize(size); SetCursor( *wxSTANDARD_CURSOR ) ; + +#if wxUSE_ACCESSIBILITY + SetAccessible( GetOrCreateAccessible() ); +#endif } void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) diff -ruN orig/wxMac-2.8.12/src/tiff/tiff.h wxMac-2.8.12/src/tiff/tiff.h --- orig/wxMac-2.8.12/src/tiff/tiff.h 2011-03-22 07:34:07.000000000 -0500 +++ wxMac-2.8.12/src/tiff/tiff.h 2015-05-15 12:06:29.000000000 -0500 @@ -83,8 +83,8 @@ typedef int int32; typedef unsigned int uint32; /* sizeof (uint32) must == 4 */ #else -typedef long int32; -typedef unsigned long uint32; /* sizeof (uint32) must == 4 */ +typedef int int32; +typedef unsigned int uint32; /* sizeof (uint32) must == 4 */ #endif #endif /* _TIFF_DATA_TYPEDEFS_ */