Merge lp:~alanbell/compiz/texttracking into lp:compiz/0.9.8

Proposed by Alan Bell
Status: Work in progress
Proposed branch: lp:~alanbell/compiz/texttracking
Merge into: lp:compiz/0.9.8
Diff against target: 1249 lines (+1101/-2)
13 files modified
plugins/accessibility/AUTHORS (+1/-0)
plugins/accessibility/CMakeLists.txt (+5/-0)
plugins/accessibility/VERSION (+1/-0)
plugins/accessibility/accessibility.xml.in (+17/-0)
plugins/accessibility/compiz-accessibility.pc.in (+12/-0)
plugins/accessibility/include/accessibility/accessibility.h (+217/-0)
plugins/accessibility/src/accessibility.cpp (+651/-0)
plugins/accessibility/src/private.h (+113/-0)
plugins/ezoom/CMakeLists.txt (+1/-1)
plugins/ezoom/ezoom.xml.in (+2/-0)
plugins/ezoom/src/ezoom.cpp (+71/-0)
plugins/ezoom/src/ezoom.h (+9/-0)
plugins/mousepoll/mousepoll.xml.in (+1/-1)
To merge this branch: bzr merge lp:~alanbell/compiz/texttracking
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Fixing
Sam Spilsbury Needs Fixing
Review via email: mp+111710@code.launchpad.net

Description of the change

merges in code from
https://github.com/gloob/gloob-Ezoom-fork
https://github.com/gloob/compiz-accessibility-plugin
fixing lp:#727290
it compiles, might have an additional dependency on at-spi stuff, I don't know how to merge it with the debian packaging to make an installable package.

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :
Download full text (9.2 KiB)

Looks good, and definitely on the right track, needs some work before we can merge it in, but definitely something we can have for 12.10

The README can probably be cut down or go entirely, it seems to be mostly about how to enable AT-SPI and how to build and install the plugin, which is mostly redundant anyways as the buildsystem will build it for us.

There are a few indentation problems that need to be fixed. Indentation in compiz is a little weird (X11 style). It goes:

4 spaces
8-wide tab
8-wide tab + 4 spaces
8-wide tab + 8 wide tab
8-wide tab + 8-wide tab + 4 spaces

etc

So some areas where this needs to be fixed are:

215 + virtual AccessibilityEntity *
216 + clone () const;
217 +
218 + AtspiAccessible *
219 + getObject ();

215 + virtual AccessibilityEntity *
216 + clone () const;
217 +
218 + AtspiAccessible *
219 + getObject ();

412 + for (int i = 0; i < len; i++) {
413 +

The brace goes on the next line, eg
for (int i = 0; i < len; i++)
{

 + switch (iface) {

ditto

518 + compLogMessage ("Accessibility", CompLogLevelInfo,
519 + "AccessibilityEntity::AccessibilityEntity (%s)\n", object->name);
520 +

I don't think these messages are necessary. Program function can be verified through unit tests (which I'll get on to in a minute)

1269 + if (a11yHandle->active ())
1270 + a11yHandle->unregisterAll ();

That needs to be a tab and not four spaces.

The second big thing I have about this code is that the design feels a little weird.

The inheritance hierarchy looks a bit like this:

AccessibilityEntity
 - AccessibilityComponent
 - AccessibilityText

AccessibleObject (which appears to be a wrapper around AtspiAccessible *)
Accessibility (which appears to be a manager class)

The real gripe I have here are things like this:

434 + case Component:
435 + entity = AccessibilityEntity::Ptr (new AccessibilityComponent (object));
436 + break;
437 +
438 + case Text:
439 + entity = AccessibilityEntity::Ptr (new AccessibilityText (object));
440 + break;
441 +
442 + case Accessible:
443 + case Action:
444 + case Collection:
445 + case Document:
446 + case EditableText:
447 + case Hypertext:
448 + case Hyperlink:
449 + case Image:
450 + case Selection:
451 + case Table:
452 + case Value:
453 + break;
454 +
455 + default:
456 + entity = AccessibilityEntity::Ptr (new AccessibilityEntity (object));

This code feels fragile, because our fallback case is "silently do nothing", and we just waste memory by tracking objects we don't really care about. Moreover, that behaviour is different from cases that we know we don't care about where we return a shared_ptr to NULL and then the client code just assumes that the pointer is valid.

There are other examples like this:

941 + if (object->is (Component))
942 + {
943 +
944 + AccessibilityComponent::Ptr ac =
945 + boost::static_pointer_cast<AccessibilityComponent>
946 + (object->getEntity (Component));

Generally speaking, code where you need to go from some "placeholder" down to something that you think the object is feels to me like reintepret_casting through void * with a note that everything will be okay.

I understand that Atspi is based on GObject and as such, you have to handle the type system at run...

Read more...

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Oh yeah, totally forgot! Tests...

Generally speaking, I prefer all code going into compiz to come with unit tests. I don't think getting this particular code under test will be that difficult. The majority of the a11y code looks like its just wrappers for managing objects coming to us from AT-SPI.

Stuff that I think needs to be tested (or needs to be deleted, since it looks unused):

206 + virtual bool
207 + load (AtspiAccessible *);
208 +
209 + virtual bool
210 + contains (AccessibilityEntity *, int, int);
211 +

Actually they can be deleted completely as they are unused. But...

236 + CompRect
237 + getExtents () const;
238 +
239 + CompPoint
240 + getPosition () const;
241 +
242 + CompPoint
243 + getSize () const;

I am like 99% sure the second two are unused.

The relationship between getExtents and this:

1214 + if (optionGetZoomMode () == EzoomOptions::ZoomModePanArea)
1215 + {
1216 + ensureVisibilityArea (rect.x1(),
1217 + rect.y1(),
1218 + rect.x2(),
1219 + rect.y2(),
1220 + optionGetRestrainMargin (),
1221 + NORTHWEST);
1222 + }

Or, a potential getZoomCenterArea () needs to come under test

As well as:

267 + CompRect
268 + getCharacterExtents (int) const;
269 +
270 + CompRect
271 + getRangeExtents (int) const;
272 +
273 + int
274 + getCaretOffset ();

(getRangeExtents can be deleted)

But the relationship between the first and the third needs to be tested. That means breaking the dependency on

654 + AtspiRect *character_rect = atspi_text_get_character_extents
655 + (text, offset, ATSPI_COORD_TYPE_SCREEN, &error);

through an interface by which AtspiRect can be manipulated and atspi_text_get_character_extents be queried.

Then you can use Mock Objects to verify the behaviour of getCharacterExtents and the resulting zoom rect.

Feel free to poke with questions on IRC. I'm on planes for the next two days, but I can be found on freenode (nick: smspillaz)

lp:~alanbell/compiz/texttracking updated
3254. By Alan Bell

remove README and fix indentation

3255. By Alan Bell

remove message

3256. By Alan Bell

indentation issue

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Please review and fix the indentation and style again. For example:

135 + virtual IfaceType
136 + is ();
137 +
138 + virtual AccessibilityEntity *
139 + clone () const;
140 +
141 + AtspiAccessible *
142 + getObject ();

should be more like:

   virtual IfaceType is ();
   virtual AccessibilityEntity *clone () const;
   AtspiAccessible *getObject ();

And the same applies elsewhere.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

When done, please click Resubmit so we get notified.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Please also click "Set commit message" when done so the automerger doesn't reject it once approved by us.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

(This will be looked at and I will propose a merge to fix some of the overarching design issues once the gles2 and gsettings work is done)

Revision history for this message
Alan Bell (alanbell) wrote :

I will have a go at the indentation issues, but I am a bit out of my depth on the refactoring, this isn't my code, I am just trying to integrate it into the upstream tree, I will try and contact gloob https://github.com/gloob for some help I think.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Sure, no problem :)

Revision history for this message
Alejandro Leiva (gloob) wrote :

Hi guys, thanks for working on this.

As Sam pointed out before there's some methods, classes and structures that I'm not using in the plugin. In fact I'm not happy with the global architecture. A refactor is needed. I'll do.

Alan if you can grant me write access to your branch I won't need to create a new branch and merge and so on.

Cheers.

Revision history for this message
Alan Bell (alanbell) wrote :

thanks Alejandro,

I don't think I can give you write access to my branch, but you can probably do
bzr branch lp:~alanbell/compiz/texttracking
bzr push lp:~gloob/compiz/texttracking

and then do a merge request from there

Unmerged revisions

3256. By Alan Bell

indentation issue

3255. By Alan Bell

remove message

3254. By Alan Bell

remove README and fix indentation

3253. By Alan Bell

renamed the accessibility plugin folder and fixed an unused variable in ezoom

3252. By Alan Bell

merging in text tracking zoom work by Alejandro Leiva
https://github.com/gloob/compiz-accessibility-plugin
https://github.com/gloob/gloob-Ezoom-fork

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added directory 'plugins/accessibility'
=== added file 'plugins/accessibility/AUTHORS'
--- plugins/accessibility/AUTHORS 1970-01-01 00:00:00 +0000
+++ plugins/accessibility/AUTHORS 2012-06-23 15:04:23 +0000
@@ -0,0 +1,1 @@
1Alejandro Leiva <aleiva@emergya.com>
02
=== added file 'plugins/accessibility/CMakeLists.txt'
--- plugins/accessibility/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/accessibility/CMakeLists.txt 2012-06-23 15:04:23 +0000
@@ -0,0 +1,5 @@
1find_package (Compiz REQUIRED)
2
3include (CompizPlugin)
4
5compiz_plugin (accessibility PKGDEPS atspi-2)
06
=== added file 'plugins/accessibility/ChangeLog'
=== added file 'plugins/accessibility/NEWS'
=== added file 'plugins/accessibility/VERSION'
--- plugins/accessibility/VERSION 1970-01-01 00:00:00 +0000
+++ plugins/accessibility/VERSION 2012-06-23 15:04:23 +0000
@@ -0,0 +1,1 @@
10.9.5.0
02
=== added file 'plugins/accessibility/accessibility.xml.in'
--- plugins/accessibility/accessibility.xml.in 1970-01-01 00:00:00 +0000
+++ plugins/accessibility/accessibility.xml.in 2012-06-23 15:04:23 +0000
@@ -0,0 +1,17 @@
1<?xml version="1.0"?>
2<compiz>
3 <plugin name="accessibility" useBcop="true">
4 <_short>Accessibility</_short>
5 <_long>Activate compatibility with accessibility layer.</_long>
6 <category>Accessibility</category>
7 <deps>
8 <relation type="after">
9 <plugin>opengl</plugin>
10 <plugin>composite</plugin>
11 <plugin>decor</plugin>
12 </relation>
13 </deps>
14 <options>
15 </options>
16 </plugin>
17</compiz>
018
=== added file 'plugins/accessibility/compiz-accessibility.pc.in'
--- plugins/accessibility/compiz-accessibility.pc.in 1970-01-01 00:00:00 +0000
+++ plugins/accessibility/compiz-accessibility.pc.in 2012-06-23 15:04:23 +0000
@@ -0,0 +1,12 @@
1prefix=@prefix@
2exec_prefix=@prefix@
3libdir=@libdir@
4includedir=@includedir@
5
6Name: compiz-accessibility
7Description: Accessibility (based in AT-SPI2) plugin for compiz
8Version: @VERSION@
9
10Requires: compiz
11Libs: -L${libdir}/compiz -laccessibility
12Cflags: @COMPIZ_CFLAGS@ -I${includedir}/compiz
013
=== added directory 'plugins/accessibility/include'
=== added directory 'plugins/accessibility/include/accessibility'
=== added file 'plugins/accessibility/include/accessibility/accessibility.h'
--- plugins/accessibility/include/accessibility/accessibility.h 1970-01-01 00:00:00 +0000
+++ plugins/accessibility/include/accessibility/accessibility.h 2012-06-23 15:04:23 +0000
@@ -0,0 +1,217 @@
1/*
2 * Compiz Accessibility PLugin
3 *
4 * Copyright (c) 2011 F123 Consulting & Mais Diferenças
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * Author: Alejandro Leiva <aleiva@emergya.com>
17 *
18 */
19
20#ifndef _ACCESSIBILITY_H
21#define _ACCESSIBILITY_H
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26#include <atspi/atspi.h>
27#ifdef __cplusplus
28}
29#endif
30
31/*
32 * Class hierarchy that hold and manage differents accessible objects.
33 */
34enum IfaceType
35{
36 Accessible = 0,
37 Action,
38 Collection,
39 Component,
40 Document,
41 EditableText,
42 Hypertext,
43 Hyperlink,
44 Image,
45 Selection,
46 Table,
47 Text,
48 Value,
49};
50
51class AccessibilityEntity
52{
53 public:
54 typedef boost::shared_ptr<AccessibilityEntity> Ptr;
55
56 AccessibilityEntity (AtspiAccessible *);
57 virtual ~AccessibilityEntity ();
58
59 virtual bool
60 load (AtspiAccessible *);
61
62 virtual bool
63 contains (AccessibilityEntity *, int, int);
64
65 virtual IfaceType
66 is ();
67
68 virtual AccessibilityEntity *
69 clone () const;
70
71 AtspiAccessible *
72 getObject ();
73
74 protected:
75 AtspiAccessible * obj;
76};
77
78class AccessibilityComponent :
79 public AccessibilityEntity
80{
81 public:
82 typedef boost::shared_ptr<AccessibilityComponent> Ptr;
83
84 AccessibilityComponent (AtspiAccessible *);
85
86 virtual AccessibilityComponent *
87 clone () const;
88
89 CompRect
90 getExtents () const;
91
92 CompPoint
93 getPosition () const;
94
95 CompPoint
96 getSize () const;
97
98 virtual IfaceType
99 is ();
100
101 /* TODO: Implement based in a compiz layer type.
102 CompLayer
103 getLayer ();
104 */
105 protected:
106 AtspiComponent *component;
107};
108
109class AccessibilityText :
110 public AccessibilityEntity
111{
112 public:
113 typedef boost::shared_ptr<AccessibilityText> Ptr;
114
115 AccessibilityText (AtspiAccessible *);
116
117 virtual AccessibilityText *
118 clone () const;
119
120 CompRect
121 getCharacterExtents (int) const;
122
123 CompRect
124 getRangeExtents (int) const;
125
126 int
127 getCaretOffset ();
128
129 virtual IfaceType
130 is ();
131
132 protected:
133 AtspiText *text;
134};
135
136class AccessibleObject
137{
138 public:
139 typedef std::vector <AccessibilityEntity::Ptr> Entities;
140 typedef std::vector <IfaceType> Interfaces;
141
142 AccessibleObject (AtspiAccessible *);
143
144 AccessibleObject::Entities
145 create (AtspiAccessible *);
146
147 AccessibilityEntity::Ptr
148 get (IfaceType);
149
150 bool
151 is (IfaceType);
152
153 AccessibilityEntity::Ptr
154 getEntity (IfaceType);
155
156 private:
157 AccessibilityEntity::Ptr
158 instantiate (AtspiAccessible *, IfaceType);
159
160 static IfaceType
161 enumFromStr (const char *);
162
163 int
164 getIfaceIndex (IfaceType);
165
166 private:
167 Entities ents;
168 Interfaces interfaces;
169 AtspiAccessible * obj;
170};
171
172class AccessibilityEvent
173{
174 public:
175 AccessibilityEvent (const AtspiEvent *);
176 ~AccessibilityEvent ();
177
178 const char *
179 getType ();
180
181 AccessibleObject *
182 getAccessibleObject ();
183
184 private:
185 const AtspiEvent *event;
186 AccessibleObject *object;
187
188};
189
190typedef boost::function<void (AccessibilityEvent *)> AccessibilityEventCallback;
191
192class Accessibility
193{
194 public:
195
196 Accessibility ();
197 ~Accessibility ();
198
199 bool
200 start ();
201
202 bool
203 stop ();
204
205 bool
206 active ();
207
208 bool
209 registerEventHandler (const char *, AccessibilityEventCallback);
210
211 void
212 unregisterAll ();
213
214 friend class AccessibilityScreen;
215};
216
217#endif // _ACCESSIBILITY_H
0218
=== added directory 'plugins/accessibility/src'
=== added file 'plugins/accessibility/src/accessibility.cpp'
--- plugins/accessibility/src/accessibility.cpp 1970-01-01 00:00:00 +0000
+++ plugins/accessibility/src/accessibility.cpp 2012-06-23 15:04:23 +0000
@@ -0,0 +1,651 @@
1/*
2 * Compiz Accessibility PLugin
3 *
4 * Copyright (c) 2011 F123 Consulting & Mais Diferenças
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * Author: Alejandro Leiva <aleiva@emergya.com>
17 *
18 */
19
20#include "private.h"
21
22COMPIZ_PLUGIN_20090315 (accessibility, AccessibilityPluginVTable);
23
24AccessibleObject::AccessibleObject (AtspiAccessible *object)
25{
26 compLogMessage ("Accessibility", CompLogLevelInfo,
27 "AccessibleObject::AccessibleObject (%s)\n", object->name);
28
29 obj = object;
30
31 create (object);
32}
33
34AccessibleObject::Entities
35AccessibleObject::create (AtspiAccessible *object)
36{
37 GArray * ifaces = atspi_accessible_get_interfaces (object);
38
39 int len = (int) ifaces->len;
40
41 for (int i = 0; i < len; i++)
42 {
43
44 char *iface = (char *) g_array_index (ifaces, gchar *, i);
45
46 interfaces.push_back (enumFromStr (iface));
47 // Defer the creation of the AccessibilityEntity structure.
48 // TODO: Create a new method to create it from AccessibleObject.
49 //ents.push_back (instantiate (object, iface));
50 }
51
52 g_array_free (ifaces, TRUE);
53
54 return ents;
55}
56
57AccessibilityEntity::Ptr
58AccessibleObject::instantiate (AtspiAccessible *object, IfaceType iface)
59{
60 AccessibilityEntity::Ptr entity;
61
62 switch (iface)
63 {
64
65 case Component:
66 entity = AccessibilityEntity::Ptr (new AccessibilityComponent (object));
67 break;
68
69 case Text:
70 entity = AccessibilityEntity::Ptr (new AccessibilityText (object));
71 break;
72
73 case Accessible:
74 case Action:
75 case Collection:
76 case Document:
77 case EditableText:
78 case Hypertext:
79 case Hyperlink:
80 case Image:
81 case Selection:
82 case Table:
83 case Value:
84 break;
85
86 default:
87 entity = AccessibilityEntity::Ptr (new AccessibilityEntity (object));
88 }
89
90 return entity;
91}
92
93IfaceType
94AccessibleObject::enumFromStr (const char *str)
95{
96
97 for (int i = 0; i < NUM_IFACES_SUPPORTED; i++)
98 if (!strcmp (IfaceTypeStr[i], str))
99 return (IfaceType) i;
100
101 return Accessible;
102}
103
104AccessibilityEntity::Ptr
105AccessibleObject::get (IfaceType type)
106{
107 int index = getIfaceIndex (type);
108 compLogMessage ("Accessibility", CompLogLevelInfo, "AccessibleObject::get(%s) = %d\n",
109 type, index);
110
111 if (index < 0)
112 return AccessibilityEntity::Ptr ();
113
114 return ents[index];
115}
116
117bool
118AccessibleObject::is (IfaceType type)
119{
120 int index = getIfaceIndex (type);
121
122 if (index < 0)
123 return false;
124
125 return true;
126}
127
128int
129AccessibleObject::getIfaceIndex (IfaceType type)
130{
131 for (int i = 0; i < (int) interfaces.size(); i++)
132 {
133 if (type == interfaces[i])
134 return i;
135 }
136
137 return -1;
138}
139
140AccessibilityEntity::Ptr
141AccessibleObject::getEntity (IfaceType type)
142{
143 return instantiate (obj, type);
144}
145
146
147AccessibilityEntity::AccessibilityEntity (AtspiAccessible *object)
148{
149 obj = object;
150}
151
152AccessibilityEntity::~AccessibilityEntity () {
153
154}
155
156bool
157AccessibilityEntity::load (AtspiAccessible *object)
158{
159 return true;
160}
161
162bool
163AccessibilityEntity::contains (AccessibilityEntity *entity, int x, int y)
164{
165 return true;
166}
167
168IfaceType
169AccessibilityEntity::is ()
170{
171 return Accessible;
172}
173
174AccessibilityEntity *
175AccessibilityEntity::clone () const
176{
177 return new AccessibilityEntity (obj);
178}
179
180AtspiAccessible *
181AccessibilityEntity::getObject () {
182 return obj;
183}
184
185
186AccessibilityComponent::AccessibilityComponent (AtspiAccessible *obj) :
187 AccessibilityEntity (obj)
188{
189 compLogMessage ("Accessibility", CompLogLevelInfo,
190 "AccessibilityComponent::AccessibilityComponent (%s)\n", obj->name);
191
192 component = atspi_accessible_get_component (obj);
193}
194
195AccessibilityComponent *
196AccessibilityComponent::clone () const
197{
198 return new AccessibilityComponent (obj);
199}
200
201CompRect
202AccessibilityComponent::getExtents () const
203{
204 CompRect rect;
205 GError *error = NULL;
206
207 AtspiRect *component_rect =
208 atspi_component_get_extents (component, ATSPI_COORD_TYPE_SCREEN, &error);
209
210 if (!component_rect)
211 g_error_free (error);
212 else
213 rect = CompRect (component_rect->x,
214 component_rect->y,
215 component_rect->width,
216 component_rect->height);
217
218 return rect;
219}
220
221CompPoint
222AccessibilityComponent::getPosition () const
223{
224 CompPoint position;
225 GError *error = NULL;
226
227 AtspiPoint *component_position =
228 atspi_component_get_position (component, ATSPI_COORD_TYPE_SCREEN, &error);
229
230 if (!component_position)
231 g_error_free (error);
232 else
233 position = CompPoint (component_position->x, component_position->y);
234
235 return position;
236}
237
238CompPoint
239AccessibilityComponent::getSize () const
240{
241 CompPoint size;
242 GError *error = NULL;
243
244 AtspiPoint *component_size = atspi_component_get_size (component, &error);
245
246 if (!component_size)
247 g_error_free (error);
248 else
249 size = CompPoint (component_size->x, component_size->y);
250
251 return size;
252}
253
254IfaceType
255AccessibilityComponent::is ()
256{
257 return Component;
258}
259
260
261AccessibilityText::AccessibilityText (AtspiAccessible *obj) :
262 AccessibilityEntity (obj)
263{
264 compLogMessage ("Accessibility", CompLogLevelInfo,
265 "AccessibilityText::AccessibilityText (%s)\n", obj->name);
266
267 text = atspi_accessible_get_text (obj);
268}
269
270AccessibilityText *
271AccessibilityText::clone () const
272{
273 return new AccessibilityText (obj);
274}
275
276CompRect
277AccessibilityText::getCharacterExtents (int offset) const
278{
279 CompRect rect;
280 GError *error = NULL;
281
282 AtspiRect *character_rect = atspi_text_get_character_extents
283 (text, offset, ATSPI_COORD_TYPE_SCREEN, &error);
284
285 if (!character_rect)
286 g_error_free (error);
287 else
288 rect = CompRect (character_rect->x,
289 character_rect->y,
290 character_rect->width,
291 character_rect->height);
292
293 return rect;
294}
295
296CompRect
297AccessibilityText::getRangeExtents (int offset) const
298{
299 CompRect rect;
300 GError *error = NULL;
301
302 AtspiRect *range_rect = atspi_text_get_range_extents
303 (text, 0, 0, ATSPI_COORD_TYPE_SCREEN, &error);
304
305 if (!range_rect)
306 g_error_free (error);
307 else
308 rect = CompRect (range_rect->x,
309 range_rect->y,
310 range_rect->width,
311 range_rect->height);
312
313 return rect;
314}
315
316int
317AccessibilityText::getCaretOffset ()
318{
319 GError *error = NULL;
320
321 int caret_offset = atspi_text_get_caret_offset (text, &error);
322
323 if (!caret_offset)
324 g_error_free (error);
325
326 return caret_offset;
327}
328
329IfaceType
330AccessibilityText::is ()
331{
332 return Text;
333}
334
335
336Accessibility::Accessibility ()
337{
338 compLogMessage ("Accessibility", CompLogLevelInfo,
339 "Accessibility constructor called.\n");
340
341}
342
343Accessibility::~Accessibility ()
344{
345 compLogMessage ("Accessibility", CompLogLevelInfo,
346 "Accessibility destructor called.\n");
347
348}
349
350bool
351Accessibility::start ()
352{
353 return true;
354}
355
356bool
357Accessibility::stop ()
358{
359 return true;
360}
361
362bool
363Accessibility::active ()
364{
365 return true;
366}
367
368bool
369Accessibility::registerEventHandler (const char *event_type, AccessibilityEventCallback cb)
370{
371 ACCESSIBILITY_SCREEN (screen);
372
373 as->registerEventHandler (event_type, cb);
374
375 return true;
376}
377
378void
379Accessibility::unregisterAll ()
380{
381 ACCESSIBILITY_SCREEN (screen);
382
383 as->unregisterAll ();
384}
385
386void
387staticAccessibilityEventCallback (const AtspiEvent *event)
388{
389 if (!event)
390 return;
391
392 ACCESSIBILITY_SCREEN (screen);
393
394 AccessibilityHandlerList list = as->list;
395
396 std::list<AccessibilityHandler *>::iterator it;
397
398 AccessibilityEvent *e = new AccessibilityEvent (event);
399
400 for (it = list.begin (); it != list.end (); it++)
401 {
402 const char * target_type = (*it)->event_type;
403
404 if (strncmp (target_type, event->type, strlen(target_type)) == 0)
405 {
406 compLogMessage ("Accessibility", CompLogLevelInfo,
407 "Delegating (%s) to -> functor [%d][%s]\n",
408 event->type,
409 (*it)->id, (*it)->event_type);
410
411 (*it)->cb (e);
412 }
413 }
414
415 delete (e);
416}
417
418void
419staticAccessibilityEventDestroyCallback (void *data)
420{
421 ACCESSIBILITY_SCREEN (screen);
422
423 AccessibilityHandlerList list = as->list;
424
425 std::list<AccessibilityHandler *>::iterator it;
426
427 for (it = list.begin (); it != list.end (); it++)
428 {
429 compLogMessage ("Accessibility", CompLogLevelInfo,
430 "Delegating destroy to -> functor [%d][%s]\n",
431 (*it)->id);
432 // TODO: Implement callback mechanism for handles destroy.
433 }
434}
435
436AccessibilityEvent::AccessibilityEvent (const AtspiEvent *event)
437{
438 this->event = event;
439 this->object = new AccessibleObject (event->source);
440}
441
442AccessibilityEvent::~AccessibilityEvent ()
443{
444 delete (event);
445 delete (object);
446}
447
448const char *
449AccessibilityEvent::getType ()
450{
451 return event->type;
452}
453
454AccessibleObject *
455AccessibilityEvent::getAccessibleObject ()
456{
457 return object;
458}
459
460AccessibilityEventHandler
461AccessibilityScreen::registerEventHandler (const char *event_type,
462 AccessibilityEventCallback cb)
463{
464
465 AccessibilityHandler *hnd = new AccessibilityHandler ();
466
467 if (!hnd)
468 return 0;
469
470 if (!event_type || !cb)
471 return 0;
472
473 // Create event listeners
474 GError *error = NULL;
475
476 AtspiEventListener *event_listener =
477 atspi_event_listener_new_simple (staticAccessibilityEventCallback,
478 staticAccessibilityEventDestroyCallback);
479
480 if (!atspi_event_listener_register (event_listener, event_type, &error))
481 {
482 compLogMessage ("Accessibility", CompLogLevelInfo,
483 "Cannot create event listener (%s). [%s]\n",
484 event_type,
485 error->message);
486
487 g_error_free (error);
488 error = NULL;
489 }
490
491 hnd->event_type = event_type;
492 hnd->event_listener = event_listener;
493 hnd->cb = cb;
494 hnd->id = lastEventHandler++;
495
496 list.push_front (hnd);
497
498 compLogMessage ("Accessibility", CompLogLevelInfo, "Registered new listener (%d): (%s))\n", hnd->id, hnd->event_type);
499
500 return hnd->id;
501}
502
503void
504AccessibilityScreen::unregisterEventHandler (AccessibilityEventHandler handler)
505{
506
507 std::list<AccessibilityHandler *>::iterator it;
508 AccessibilityHandler *h;
509
510 if (list.size() < 0)
511 return;
512
513 for (it = list.begin (); it != list.end (); it++)
514 if ((*it)->id == handler)
515 break;
516
517 if (it == list.end ())
518 return;
519
520 // Unregister event.
521 GError *error = NULL;
522
523 if (!atspi_event_listener_deregister ((*it)->event_listener, (*it)->event_type, &error))
524 {
525 compLogMessage ("Accessibility", CompLogLevelInfo,
526 "Cannot unregister event listener (%s). [%s]\n",
527 (*it)->event_type,
528 error->message);
529
530 g_error_free (error);
531 error = NULL;
532 }
533
534 // Free and erase from the list.
535 h = (*it);
536 delete (h);
537
538 list.erase (it);
539}
540
541
542bool
543AccessibilityScreen::unregisterByType (const char * event_type)
544{
545 //TODO
546 return true;
547}
548
549void
550AccessibilityScreen::unregisterAll ()
551{
552 std::list<AccessibilityHandler *>::iterator it;
553
554 if (list.size () < 0)
555 return;
556
557 for (it = list.begin (); it != list.end (); it++)
558 {
559 unregisterEventHandler ((*it)->id);
560 }
561}
562
563void
564AccessibilityScreen::handleAccessibilityEvent (AccessibilityEvent *event)
565{
566
567 AccessibleObject *object = event->getAccessibleObject ();
568
569 if (object->is (Component))
570 {
571
572 AccessibilityComponent::Ptr ac =
573 boost::static_pointer_cast<AccessibilityComponent>
574 (object->getEntity (Component));
575
576 CompRect rect = ac->getExtents ();
577
578 compLogMessage ("Accessibility", CompLogLevelInfo, "Object is Component\n");
579
580 compLogMessage ("Accessibility", CompLogLevelInfo,
581 "Component Area [%d, %d] [%d, %d]\n",
582 rect.x1(), rect.y1(), rect.x2(), rect.y2());
583 }
584 else
585 {
586
587 compLogMessage ("Accessibility", CompLogLevelInfo, "Object is NOT Component\n");
588 }
589}
590
591AccessibilityScreen::AccessibilityScreen (CompScreen *screen) :
592 PluginClassHandler <AccessibilityScreen, CompScreen> (screen),
593 screen (screen),
594 lastEventHandler (0)
595{
596 compLogMessage ("Accessibility", CompLogLevelInfo,
597 "AccessibilityScreen called.\n");
598
599 /* TODO: Check atspi_init() code. There's a memory leak when registryd
600 * isn't running.
601 */
602 int atspi_status = atspi_init ();
603
604 compLogMessage ("Accessibility", CompLogLevelInfo,
605 "AccessibilityScreen: AT-SPI init() %d.\n", atspi_status);
606
607 /*
608 registerEventHandler ("object:state-changed:", boost::bind (
609 &AccessibilityScreen::handleAccessibilityEvent, this, _1));
610 */
611
612 compLogMessage ("Accessibility", CompLogLevelInfo, "Running!\n");
613
614 /*
615 // Launch main event atspi loop
616 // This is not needed because compiz private screen launches its own
617 // Glib MainLoop
618 */
619 /*
620
621 atspi_event_main();
622 */
623}
624
625AccessibilityScreen::~AccessibilityScreen ()
626{
627
628 unregisterAll ();
629
630 //atspi_event_quit();
631 int atspi_status = atspi_exit ();
632
633 compLogMessage ("Accessibility", CompLogLevelInfo,
634 "~AccessibilityScreen called. Exit value: %d\n", atspi_status);
635}
636
637bool
638AccessibilityPluginVTable::init ()
639{
640 if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
641 {
642 compLogMessage ("Accessibility", CompLogLevelInfo,
643 "compiz core not in sync.\n");
644 return false;
645 }
646
647 compLogMessage ("Accessibility", CompLogLevelInfo,
648 "Running Accessibility plugin.\n");
649
650 return true;
651}
0652
=== added file 'plugins/accessibility/src/private.h'
--- plugins/accessibility/src/private.h 1970-01-01 00:00:00 +0000
+++ plugins/accessibility/src/private.h 2012-06-23 15:04:23 +0000
@@ -0,0 +1,113 @@
1/*
2 * Compiz Accessibility PLugin
3 *
4 * Copyright (c) 2011 F123 Consulting & Mais Diferenças
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * Author: Alejandro Leiva <aleiva@emergya.com>
17 *
18 */
19
20#include <vector>
21#include <cstring>
22
23#include <boost/shared_ptr.hpp>
24
25#include <core/core.h>
26#include <core/pluginclasshandler.h>
27
28#include <glibmm/main.h>
29
30#include <accessibility/accessibility.h>
31#include "accessibility_options.h"
32
33static const char *IfaceTypeStr[] =
34{
35 "Accessible",
36 "Action",
37 "Collection",
38 "Component",
39 "Document",
40 "EditableText",
41 "Hypertext",
42 "Hyperlink",
43 "Image",
44 "Selection",
45 "Table",
46 "Text",
47 "Value",
48};
49
50#define NUM_IFACES_SUPPORTED 13
51
52typedef int AccessibilityEventHandler;
53
54/* Struct of a handler and list of handlers */
55struct AccessibilityHandler {
56 const char * event_type;
57 AtspiEventListener * event_listener;
58 AccessibilityEventCallback cb;
59 AccessibilityEventHandler id;
60};
61
62typedef std::list<AccessibilityHandler *> AccessibilityHandlerList;
63
64class AccessibilityScreen :
65 public PluginClassHandler <AccessibilityScreen, CompScreen>,
66 public ScreenInterface,
67 public AccessibilityOptions
68{
69 public:
70
71 AccessibilityScreen (CompScreen *);
72 ~AccessibilityScreen ();
73
74 CompScreen *screen;
75
76 AccessibilityEventHandler
77 registerEventHandler (const char * event_type,
78 AccessibilityEventCallback cb);
79
80 void
81 unregisterEventHandler (AccessibilityEventHandler handler);
82
83 bool
84 unregisterByType (const char * event_type);
85
86 void
87 unregisterAll ();
88
89 void
90 handleAccessibilityEvent (AccessibilityEvent *);
91
92 public:
93
94 AccessibilityHandlerList list;
95 int lastEventHandler;
96
97 protected:
98
99 AtspiEventListener *listener;
100
101};
102
103#define ACCESSIBILITY_SCREEN(s) \
104 AccessibilityScreen *as = AccessibilityScreen::get (s)
105
106class AccessibilityPluginVTable :
107 public CompPlugin::VTableForScreen <AccessibilityScreen>
108{
109 public:
110
111 bool init();
112
113};
0114
=== modified file 'plugins/ezoom/CMakeLists.txt'
--- plugins/ezoom/CMakeLists.txt 2012-05-16 17:40:27 +0000
+++ plugins/ezoom/CMakeLists.txt 2012-06-23 15:04:23 +0000
@@ -2,4 +2,4 @@
22
3include (CompizPlugin)3include (CompizPlugin)
44
5compiz_plugin (ezoom PLUGINDEPS composite opengl mousepoll)5compiz_plugin (ezoom PLUGINDEPS composite opengl mousepoll accessibility PKGDEPS atspi-2)
66
=== modified file 'plugins/ezoom/ezoom.xml.in'
--- plugins/ezoom/ezoom.xml.in 2012-05-16 17:40:27 +0000
+++ plugins/ezoom/ezoom.xml.in 2012-06-23 15:04:23 +0000
@@ -6,6 +6,7 @@
6 <plugin>opengl</plugin>6 <plugin>opengl</plugin>
7 <plugin>expo</plugin>7 <plugin>expo</plugin>
8 <plugin>decor</plugin>8 <plugin>decor</plugin>
9 <plugin>accessibility</plugin>
9 </relation>10 </relation>
10 <relation type="before">11 <relation type="before">
11 <plugin>staticswitcher</plugin>12 <plugin>staticswitcher</plugin>
@@ -14,6 +15,7 @@
14 <requirement>15 <requirement>
15 <plugin>opengl</plugin>16 <plugin>opengl</plugin>
16 <plugin>mousepoll</plugin>17 <plugin>mousepoll</plugin>
18 <plugin>accessibility</plugin>
17 </requirement>19 </requirement>
18 </deps>20 </deps>
19 <_short>Enhanced Zoom Desktop</_short>21 <_short>Enhanced Zoom Desktop</_short>
2022
=== modified file 'plugins/ezoom/src/ezoom.cpp'
--- plugins/ezoom/src/ezoom.cpp 2012-05-18 06:52:20 +0000
+++ plugins/ezoom/src/ezoom.cpp 2012-06-23 15:04:23 +0000
@@ -604,6 +604,12 @@
604 mouse = MousePoller::getCurrentPosition ();604 mouse = MousePoller::getCurrentPosition ();
605}605}
606606
607void
608EZoomScreen::enableAccessibility ()
609{
610 ;
611}
612
607/* Sets the zoom (or scale) level.613/* Sets the zoom (or scale) level.
608 * Cleans up if we are suddenly zoomed out.614 * Cleans up if we are suddenly zoomed out.
609 */615 */
@@ -1790,6 +1796,62 @@
1790 screen->handleEvent (event);1796 screen->handleEvent (event);
1791}1797}
17921798
1799void
1800EZoomScreen::handleAccessibilityEvent (AccessibilityEvent *event)
1801{
1802 AccessibleObject *object = event->getAccessibleObject ();
1803
1804 compLogMessage ("EZoom", CompLogLevelInfo,
1805 "event->type: %s\n", event->getType());
1806
1807 if (object->is (Component))
1808 {
1809
1810 AccessibilityComponent::Ptr ac =
1811 boost::static_pointer_cast<AccessibilityComponent>
1812 (object->getEntity (Component));
1813
1814 CompRect rect = ac->getExtents ();
1815
1816 compLogMessage ("Ezoom", CompLogLevelInfo,
1817 "ensureVisibilityArea [%d, %d] [%d, %d]\n",
1818 rect.x1(), rect.y1(), rect.x2(), rect.y2());
1819
1820 if (optionGetZoomMode () == EzoomOptions::ZoomModePanArea)
1821 {
1822 ensureVisibilityArea (rect.x1(),
1823 rect.y1(),
1824 rect.x2(),
1825 rect.y2(),
1826 optionGetRestrainMargin (),
1827 NORTHWEST);
1828 }
1829 }
1830
1831 if (object->is (Text))
1832 {
1833 AccessibilityText::Ptr at =
1834 boost::static_pointer_cast<AccessibilityText>
1835 (object->getEntity (Text));
1836
1837 CompRect rect = at->getCharacterExtents (at->getCaretOffset ());
1838
1839 compLogMessage ("Ezoom", CompLogLevelInfo,
1840 "TEXT - [%d, %d] [%d, %d]\n",
1841 rect.x1(), rect.y1(), rect.x2(), rect.y2());
1842
1843 if (optionGetZoomMode () == EzoomOptions::ZoomModePanArea)
1844 {
1845 ensureVisibilityArea (rect.x1(),
1846 rect.y1(),
1847 rect.x2(),
1848 rect.y2(),
1849 optionGetRestrainMargin (),
1850 NORTHWEST);
1851 }
1852 }
1853}
1854
1793/* TODO: Use this ctor carefully */1855/* TODO: Use this ctor carefully */
17941856
1795EZoomScreen::CursorTexture::CursorTexture () :1857EZoomScreen::CursorTexture::CursorTexture () :
@@ -1866,6 +1928,12 @@
1866 pollHandle.setCallback (boost::bind (1928 pollHandle.setCallback (boost::bind (
1867 &EZoomScreen::updateMouseInterval, this, _1));1929 &EZoomScreen::updateMouseInterval, this, _1));
18681930
1931 a11yHandle = new Accessibility();
1932 a11yHandle->registerEventHandler ("object:state-changed", boost::bind (
1933 &EZoomScreen::handleAccessibilityEvent, this, _1));
1934 a11yHandle->registerEventHandler ("object:text-changed", boost::bind (
1935 &EZoomScreen::handleAccessibilityEvent, this, _1));
1936
1869 optionSetZoomInButtonInitiate (boost::bind (&EZoomScreen::zoomIn, this, _1,1937 optionSetZoomInButtonInitiate (boost::bind (&EZoomScreen::zoomIn, this, _1,
1870 _2, _3));1938 _2, _3));
1871 optionSetZoomOutButtonInitiate (boost::bind (&EZoomScreen::zoomOut, this, _1,1939 optionSetZoomOutButtonInitiate (boost::bind (&EZoomScreen::zoomOut, this, _1,
@@ -1926,6 +1994,9 @@
1926 if (pollHandle.active ())1994 if (pollHandle.active ())
1927 pollHandle.stop ();1995 pollHandle.stop ();
19281996
1997 if (a11yHandle->active ())
1998 a11yHandle->unregisterAll ();
1999
1929 if (zooms.size ())2000 if (zooms.size ())
1930 zooms.clear ();2001 zooms.clear ();
19312002
19322003
=== modified file 'plugins/ezoom/src/ezoom.h'
--- plugins/ezoom/src/ezoom.h 2010-10-25 02:23:36 +0000
+++ plugins/ezoom/src/ezoom.h 2012-06-23 15:04:23 +0000
@@ -44,6 +44,7 @@
44#include <composite/composite.h>44#include <composite/composite.h>
45#include <opengl/opengl.h>45#include <opengl/opengl.h>
46#include <mousepoll/mousepoll.h>46#include <mousepoll/mousepoll.h>
47#include <accessibility/accessibility.h>
4748
4849
49#include "ezoom_options.h"50#include "ezoom_options.h"
@@ -184,6 +185,8 @@
184185
185 MousePoller pollHandle; // mouse poller object186 MousePoller pollHandle; // mouse poller object
186187
188 Accessibility *a11yHandle; // Accessibility object
189
187 private:190 private:
188191
189 bool fixesSupported;192 bool fixesSupported;
@@ -212,6 +215,9 @@
212 void215 void
213 handleEvent (XEvent *);216 handleEvent (XEvent *);
214217
218 void
219 handleAccessibilityEvent (AccessibilityEvent *event);
220
215 public:221 public:
216222
217 int223 int
@@ -250,6 +256,9 @@
250 void256 void
251 enableMousePolling ();257 enableMousePolling ();
252258
259 void
260 enableAccessibility ();
261
253 void262 void
254 setScale (int out, float value);263 setScale (int out, float value);
255264
256265
=== modified file 'plugins/mousepoll/mousepoll.xml.in'
--- plugins/mousepoll/mousepoll.xml.in 2012-05-16 17:43:36 +0000
+++ plugins/mousepoll/mousepoll.xml.in 2012-06-23 15:04:23 +0000
@@ -16,7 +16,7 @@
16 <option type="int" name="mouse_poll_interval">16 <option type="int" name="mouse_poll_interval">
17 <_short>Mouse Poll Interval</_short>17 <_short>Mouse Poll Interval</_short>
18 <_long>How often to poll the mouse position, in miliseconds. Reduce this to reduce choppy behavior.</_long>18 <_long>How often to poll the mouse position, in miliseconds. Reduce this to reduce choppy behavior.</_long>
19 <default>40</default>19 <default>10</default>
20 <min>1</min>20 <min>1</min>
21 <max>500</max>21 <max>500</max>
22 </option>22 </option>

Subscribers

People subscribed via source and target branches