Skip to content

Commit 1c4d7ab

Browse files
committed
RegistersView Accessibility
1 parent e3ffc0c commit 1c4d7ab

File tree

9 files changed

+304
-0
lines changed

9 files changed

+304
-0
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#ifndef QT_NO_ACCESSIBILITY
2+
#include "Accessible.h"
3+
4+
QAccessibleInterface* accessibleInterfaceFactory(const QString & classname, QObject* object)
5+
{
6+
QAccessibleInterface* ptr = nullptr;
7+
if((classname == "RegistersView") && object && dynamic_cast<RegistersView*>(object) != nullptr)
8+
{
9+
ptr = new AccessibleRegistersView(dynamic_cast<QWidget*>(object));
10+
}
11+
return ptr;
12+
}
13+
14+
#endif
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "AccessibleRegistersView.h"
2+
3+
QAccessibleInterface* accessibleInterfaceFactory(const QString & classname, QObject* object);
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
// This file implements accessibility interface for RegistersView
2+
#ifndef QT_NO_ACCESSIBILITY
3+
#include "AccessibleRegistersView.h"
4+
5+
AccessibleRegistersViewItem::AccessibleRegistersViewItem() : mParent(nullptr), id(RegistersView::REGISTER_NAME::CAX)
6+
{
7+
}
8+
9+
void AccessibleRegistersViewItem::setRegistersView(AccessibleRegistersView* parent, int id)
10+
{
11+
this->mParent = parent;
12+
this->id = (RegistersView::REGISTER_NAME)id;
13+
}
14+
15+
QString AccessibleRegistersViewItem::text(QAccessible::Text t) const
16+
{
17+
RegistersView* w = mParent->m_registersView;
18+
switch(t)
19+
{
20+
case QAccessible::Name:
21+
case QAccessible::Value:
22+
if(w->mLABELDISPLAY.contains(id))
23+
return QString(w->mRegisterMapping[id]) + " = " + w->GetRegStringValueFromValue(w->mSelected, w->registerValue(&w->mRegDumpStruct, w->mSelected)) + ' ' + w->getRegisterLabel(id);
24+
return QString(w->mRegisterMapping[id]) + " = " + w->GetRegStringValueFromValue(w->mSelected, w->registerValue(&w->mRegDumpStruct, w->mSelected));
25+
case QAccessible::Help:
26+
return w->helpRegister(id);
27+
default:
28+
return QString();
29+
}
30+
}
31+
32+
QColor AccessibleRegistersViewItem::foregroundColor() const
33+
{
34+
if(mParent->m_registersView->mRegisterUpdates.contains(id))
35+
{
36+
return ConfigColor("RegistersModifiedColor");
37+
}
38+
else
39+
{
40+
return ConfigColor("RegistersColor");
41+
}
42+
}
43+
44+
int AccessibleRegistersViewItem::childCount() const
45+
{
46+
return 0;
47+
}
48+
49+
QWindow* AccessibleRegistersViewItem::window() const
50+
{
51+
return mParent->window();
52+
}
53+
54+
QAccessibleInterface* AccessibleRegistersViewItem::parent() const
55+
{
56+
return dynamic_cast<QAccessibleInterface*>(mParent);
57+
}
58+
59+
QAccessibleInterface* AccessibleRegistersViewItem::child(int index) const
60+
{
61+
return nullptr;
62+
}
63+
64+
int AccessibleRegistersViewItem::indexOfChild(const QAccessibleInterface* child) const
65+
{
66+
return -1;
67+
}
68+
69+
QAccessible::Role AccessibleRegistersViewItem::role() const
70+
{
71+
return QAccessible::ListItem;
72+
}
73+
74+
QAccessible::State AccessibleRegistersViewItem::state() const
75+
{
76+
QAccessible::State state;
77+
state.focusable = mParent->m_registersView->isActive;
78+
state.active = mParent->m_registersView->isActive;
79+
state.selectable = mParent->m_registersView->isActive;
80+
if(mParent->m_registersView->mSelected == id)
81+
{
82+
state.selected = true;
83+
if(mParent->m_registersView->hasFocus())
84+
state.focused = true;
85+
}
86+
return state;
87+
}
88+
89+
QAccessibleInterface* AccessibleRegistersViewItem::childAt(int x, int y) const
90+
{
91+
return nullptr;
92+
}
93+
94+
QObject* AccessibleRegistersViewItem::object() const
95+
{
96+
return nullptr;
97+
}
98+
99+
void AccessibleRegistersViewItem::setText(QAccessible::Text t, const QString & text)
100+
{
101+
}
102+
103+
QRect AccessibleRegistersViewItem::rect() const
104+
{
105+
return QRect();
106+
}
107+
108+
bool AccessibleRegistersViewItem::isValid() const
109+
{
110+
return mParent->m_registersView->isActive;
111+
}
112+
113+
AccessibleRegistersView::AccessibleRegistersView(QWidget* w) : QAccessibleWidget(w, QAccessible::List, dynamic_cast<RegistersView*>(w)->accessibleName())
114+
{
115+
m_registersView = dynamic_cast<RegistersView*>(w);
116+
interfaces.fill(0);
117+
}
118+
119+
AccessibleRegistersView::~AccessibleRegistersView()
120+
{
121+
for(auto & i : interfaces)
122+
{
123+
if(i != 0)
124+
{
125+
QAccessible::deleteAccessibleInterface(i);
126+
}
127+
}
128+
}
129+
130+
int AccessibleRegistersView::childCount() const
131+
{
132+
return RegistersView::REGISTER_NAME::UNKNOWN;
133+
}
134+
135+
QAccessibleInterface* AccessibleRegistersView::child(int index) const
136+
{
137+
if(index >= 0 && index < childCount())
138+
{
139+
if(interfaces[index] != 0)
140+
{
141+
return QAccessible::accessibleInterface(interfaces[index]);
142+
}
143+
else
144+
{
145+
auto child = new AccessibleRegistersViewItem();
146+
child->setRegistersView(const_cast<AccessibleRegistersView*>(this), index);
147+
interfaces[index] = QAccessible::registerAccessibleInterface(child);
148+
return child;
149+
}
150+
}
151+
else
152+
return nullptr;
153+
}
154+
155+
QAccessibleInterface* AccessibleRegistersView::childAt(int x, int y) const
156+
{
157+
RegistersView::REGISTER_NAME clickedReg;
158+
QPoint local = m_registersView->mapFromGlobal(QPoint(x, y));
159+
if(m_registersView->identifyRegister(local.y(), local.x(), &clickedReg))
160+
if(clickedReg < RegistersView::UNKNOWN)
161+
return child(static_cast<int>(clickedReg));
162+
return (QAccessibleInterface*)this;
163+
}
164+
165+
QAccessibleInterface* AccessibleRegistersView::focusChild() const
166+
{
167+
return child(m_registersView->mSelected);
168+
}
169+
170+
bool AccessibleRegistersView::isValid() const
171+
{
172+
return m_registersView->isActive;
173+
}
174+
175+
QAccessible::Role AccessibleRegistersView::role() const
176+
{
177+
return QAccessible::List;
178+
}
179+
180+
QAccessible::State AccessibleRegistersView::state() const
181+
{
182+
QAccessible::State state;
183+
state.focusable = true;
184+
if(m_registersView->hasFocus())
185+
state.focused = true;
186+
state.active = m_registersView->isActive;
187+
state.multiLine = true;
188+
state.multiSelectable = false;
189+
state.disabled = !m_registersView->isActive;
190+
state.hasPopup = true;
191+
return state;
192+
}
193+
#endif
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#pragma once
2+
#ifndef QT_NO_ACCESSIBILITY
3+
#include <array>
4+
#include <QAccessibleWidget>
5+
#include "../Gui/RegistersView.h"
6+
7+
class AccessibleRegistersView;
8+
9+
class AccessibleRegistersViewItem : public QAccessibleInterface
10+
{
11+
RegistersView::REGISTER_NAME id;
12+
AccessibleRegistersView* mParent;
13+
public:
14+
AccessibleRegistersViewItem();
15+
void setRegistersView(AccessibleRegistersView* parent, int id);
16+
17+
QString text(QAccessible::Text t) const override;
18+
QColor foregroundColor() const override;
19+
QWindow* window() const override;
20+
QAccessibleInterface* parent() const override;
21+
QAccessibleInterface* child(int index) const override;
22+
QAccessibleInterface* childAt(int x, int y) const override;
23+
QObject* object() const override;
24+
void setText(QAccessible::Text t, const QString & text) override;
25+
QRect rect() const override;
26+
int indexOfChild(const QAccessibleInterface* child) const override;
27+
QAccessible::Role role() const override;
28+
QAccessible::State state() const override;
29+
int childCount() const override;
30+
bool isValid() const override;
31+
};
32+
33+
class AccessibleRegistersView : public QAccessibleWidget
34+
{
35+
mutable std::array<QAccessible::Id, (size_t)RegistersView::UNKNOWN> interfaces;
36+
friend class AccessibleRegistersViewItem;
37+
RegistersView* m_registersView;
38+
public:
39+
AccessibleRegistersView(QWidget* w);
40+
~AccessibleRegistersView();
41+
int childCount() const override;
42+
QAccessibleInterface* child(int index) const override;
43+
QAccessibleInterface* QAccessibleInterface::childAt(int x, int y) const override;
44+
QAccessibleInterface* focusChild() const override;
45+
bool isValid() const override;
46+
QAccessible::Role role() const override;
47+
QAccessible::State state() const override;
48+
};
49+
50+
#endif

src/gui/Src/Gui/CPURegistersView.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <QListWidget>
2+
#include <QAccessibleEvent>
23
#include "MiscUtil.h"
34
#include "CPUWidget.h"
45
#include "CPUDisassembly.h"
@@ -145,7 +146,10 @@ void CPURegistersView::mousePressEvent(QMouseEvent* event)
145146
emit refresh();
146147
}
147148
else
149+
{
148150
mSelected = UNKNOWN;
151+
}
152+
accessibilitySelectionChanged();
149153
}
150154
}
151155

src/gui/Src/Gui/RegistersView.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <QListWidget>
33
#include <QToolTip>
44
#include <stdint.h>
5+
#include <QAccessibleEvent>
56
#include "RegistersView.h"
67
#include "CPUDisassembly.h"
78
#include "CPUMultiDump.h"
@@ -1775,7 +1776,10 @@ void RegistersView::mousePressEvent(QMouseEvent* event)
17751776
emit refresh();
17761777
}
17771778
else
1779+
{
17781780
mSelected = UNKNOWN;
1781+
}
1782+
accessibilitySelectionChanged();
17791783
}
17801784
}
17811785

@@ -1869,6 +1873,7 @@ void RegistersView::keyPressEvent(QKeyEvent* event)
18691873
mSelected = newRegister;
18701874
ensureRegisterVisible(newRegister);
18711875
emit refresh();
1876+
accessibilitySelectionChanged();
18721877
}
18731878
}
18741879
QScrollArea::keyPressEvent(event);
@@ -3344,3 +3349,26 @@ void RegistersView::autoUpdateXMMModesAndRefresh()
33443349
// force repaint
33453350
emit refresh();
33463351
}
3352+
3353+
void RegistersView::accessibilitySelectionChanged()
3354+
{
3355+
if(QAccessible::isActive())
3356+
{
3357+
QAccessibleEvent updateEvent(static_cast<RegistersView*>(this), QAccessible::Selection);
3358+
QAccessible::updateAccessibility(&updateEvent);
3359+
if(mSelected < REGISTER_NAME::UNKNOWN)
3360+
{
3361+
QAccessibleInterface* a = QAccessible::queryAccessibleInterface(this);
3362+
if(a)
3363+
{
3364+
QAccessibleEvent focusEvent(a->child(mSelected), QAccessible::Focus);
3365+
QAccessible::updateAccessibility(&focusEvent);
3366+
}
3367+
}
3368+
else
3369+
{
3370+
QAccessibleEvent focusEvent(static_cast<RegistersView*>(this), QAccessible::Focus);
3371+
QAccessible::updateAccessibility(&updateEvent);
3372+
}
3373+
}
3374+
}

src/gui/Src/Gui/RegistersView.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,4 +298,8 @@ protected slots:
298298
QAction* SIMDHQWord;
299299
QAction* SIMDXMMSizeAuto;
300300
QAction* SIMDAlwaysShowAVX512;
301+
void accessibilitySelectionChanged();
302+
303+
friend class AccessibleRegistersView;
304+
friend class AccessibleRegistersViewItem;
301305
};

src/gui/Src/main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <QDir>
1212
#include "MiscUtil.h"
1313
#include <dwmapi.h>
14+
#include "../Accessible/Accessible.h"
1415

1516
MyApplication::MyApplication(int & argc, char** argv)
1617
: QApplication(argc, argv)
@@ -196,6 +197,9 @@ int main(int argc, char* argv[])
196197
if(x64dbgTranslator.load(QString("x64dbg_%1").arg(gCurrentLocale), path))
197198
application.installTranslator(&x64dbgTranslator);
198199

200+
// Load accessibility classes
201+
QAccessible::installFactory(accessibleInterfaceFactory);
202+
199203
// load config file + set config font
200204
mConfiguration = new Configuration;
201205
application.setFont(ConfigFont("Application"));

0 commit comments

Comments
 (0)