More work on Web Access grant
Since my last post on the web access grant, the virtual buffer library code has undergone quite a few changes, both for code readability, and for makeing sure it will really work the way it should, in all situations.
The first change is that the wm module (that manages all the window messages) has now been removed. So rather than having individual window messages for each API call that must cross a process boundary, we only now have one window message which takes a pointer to the internal function, and a pointer to a struct of arguments, as its wParam and lParam arguments. This means that only one window message needs to be registered, plus it means one less code change when adding new functions to the API.
The next change is that rather than client and internal functions using the storage buffer directly, they use a buffer container instead. This buffer container is a pointer to a struct that contains a handle to the window being virtualized, a handle to the current backend dll being used for this buffer, a pointer to the storage buffer, and a pointer to a win32 Critical Section, which is used to serialize access to the storage buffer. These changes make it much more possible to have multiple buffers for the same window, and it makes sure that the storage buffer can not be read from while its being written to etc. The latter of course depends on the fact that any backends will also properly use that critical section when accessing the storage buffer.
Previously, nodes were only used to represent tags, as in actual nodes with properties, not just text. The only way that text manifested itself was if a node was wider than 0 offsets and it had no children, or as a gap of more than 0 offsets between two sibling nodes. This was very dificult to manage when inserting and removing text, so now text has its own node type.
As Firefox3 accessibility has a *very* different way of handling text and child nodes (through its embedded object approach) compared to Firefox2, or other web browsers, a lot of long phone calls between Jamie and I were had, and a lot of code restructurig was done, to make sure that we can handle the two very different approaches as efficiently as possible.
The main problem was that the virtual buffer library was very ID-centric, meaning that all our API functions took node IDs as arguments. However, in Firefox3, text itself does not have a unique ID, so this approach just doesn't work at all. So the calls for adding and removing nodes have now been changed to take actual nodes as arguments, not just IDs. Also, the call to add a node also actually returns the node as its added, which allows the backend to gain a reference to the created node for later use. To avoid code duplication, much of the adding/removal code has ben broken down in to much smaller reusable functions, which make the code easier to read, and probably even more efficient.
Two extra functions have been added which handle the merging and splitting of text nodes. When removing a node which is flanked by two text nodes, its probably best to actually merge the two text nodes together so as not to cause fragmenting over a long period of time. Otherwise we could end up with a whole bunch of one-character wide text nodes all over the place, if there were a lot of arbitrary removals. The reason for the splitting function, is that if firefox instructs us that we need to add a node in to a parent at offset n, offset n may actually be right in the middle of a text node, so before adding the node, we need to split the text node in two at this position, and then add the new node directly after the first text node. Note that a function has not yet been written to actually take a parent and an offset from firefox and calculate where exactly in its children the new node must be added, this will get written along with the Gecko backend as its quite specific to Gecko.
Many other little fixes and tweeks have been made to the code, making sure that it handles different situations properly.
All through the writing of this code, there has been a testing program that tests different actions to perform on the storage buffer, to make sure we don't break anything.
Lately, I have branched NVDA trunk to a virtual buffer testing branch, which has allowed me to pull apart NVDA's old virtual buffers, and start writing a test one using the storage module from the virtual buffer library. Its very basic, only printing about three or so lines to a virtual buffer, with a few links and headings etc, but this is really just to enable me to start writing the necessary code in NVDA that will be used to navigate the new virtual buffer etc. I must say its quite nice to finally be able to navigate around the new virtual buffer, it does prove that this code is actually going somewhere.
One thing that Jamie and I were talking about on the phone last night was the use of hard-coded properties in the virtual buffer library, such as role, value, states, contains and shortcut. It has always been thought up until this point that backends will convert their own role and states values to virtual buffer library - sspecific ones, then NVDA only has to deal with one set. However, this seems to create a lot of work for the backends, plus rather large mappings need to be written for all the different accessibility APIs. I think we have agreed that the backends will now just use API specific values for roles and states, and NVDA itself will do any conversions after fetching them from the virtual buffer.
We are also worried about exactly what properties a node should have. Obviously a node needs an ID, as that is what makes it unique, but as far as role, value, states, contains and shortcut is concerned, these are really quite arbitrary to a virtual buffer, and specific to the API used. Our thought is that perhaps rather than having hard-coded properties, we will allow arbitrary properties instead, meaning that when a node is created, the backend who created it can specify a string of name=value pares, which denote the properties. The property names should also probably have namespaces for the different accessibility APIs, though there may be some properties which are not specific to any API.
All this needs to be thought out a little more, but what we are starting to realize is, is that the virtual buffer library should only act as a pipe line for information, at the same time tweeking the sintax and structure (i.e. converting a hyerarchical model in to a flat model), but not in any way changing the actual content. For example, the virtual buffer library should not have any idea about what a 'role' is, it should only know that nodes have properties. Its up to the actual accessibility API to inforce the semantics.
The advantage of this is that we don't need to keep changing the virtual buffer library interface when we want to add some other property, perhaps its to do with live regions, or its something to do with tables. Instead, the backend just needs to make sure it adds that particular property to the node, and of course NVDA needs to know to use that property on the other end, when its reading from the buffer.
Although work is slow, I think we are certainly making progress, and at the very least I am certainly learning a lot. This is new grround, for us at least, and I think we'll get there.
A Server for building and testing NVDA
Over the last week or so, I have been busily setting up the new testing/development server that was kindly donated to NV Access. This server is going to be used as a server for the organization: hosting a virtual private network, allowing for the collaboration of business-related work and access to NVAccess's printer/copier/scanner/fax (bought through an Australian government grant). But more importantly it will be used as a testing/development server. Once its finally set up, this server will be able to automatically build daily snapshots of NVDA (if the source code changes), and also hopefully run some automated tests on the snapshots, to make sure that changes made don't break any previous changes.
Hardware-wise, the server has a Pentium 4, 3.20 GHz processor, and 1 gig of ram. Previously it did have 2 gigs, but the second chip seemed to be not very healthy, and after taxing the memory quite a bit the other day, we were getting all sorts of fun errors, so for now that chip has been removed. It has two hard drives, one 40 gig for the main Operating System and applications, and an 80 gig for files and Virtual machines for building/testing. It also has no shortage of USB sockets, in fact I already took out one card that had four on it. It has a floppy drive, sound card, and two network cards (one for access to the internet and my home network, and one purely for NV Access, to access the printer, and any other NV Access specific devices).
I have installed Ubuntu Linux 7.10 as the server's Operating System. We chose this OS because a: both Jamie and I are used to using Debian Linux (which Ubuntu is based on) and B: Ubuntu's accessibility seems to be growing all the time. And as NV Access, this is something we'd like to keep an eye on.
For testing and building NVDA, we are going to run MS Windows inside VMWare. For those who don't know, VMWare is software that emulates an entire computer system, so you can run one operating system, inside another. There is a free version of VMWare for Linux, which suits our needs, and I have successfully installed it and its running quite nicely on the server now.
Although the server is pretty much all set up, we're still a little way off from complete automated building/testing of NVDA. One thing that needs to be completed is the re-writing of the build scripts Jamie currently uses to build NVDA snapshots on his laptop. The plan is that we'd no longer like to keep compiled copies of eSpeak, charHook, keyHook and the virtual buffer library in subversion, but instead build them along with the snapshots, and have them all included in the snapshots, and also as a separate download so that people can still run from source. However the most important part holding us back is getting access to the MS Windows Operating System, so we can install it in the virtual machines on the server. I have tested virtual machines with some other free operating systems such as Ubuntu and Gentoo Linux so I know they work, but over the next little while NV Access would like to investigate how to acquire licensed copies of the needed Windows versions. We plan to build the snapshots in Windows XP, though we would much like to be able to test NVDA with Windows 2000, Windows Vista, possibly Windows 98/ME. Of course testing MS Office would be also very useful.
Many thanks go to the donator of the server, already we are seeing just how useful it is, plus we believe it really will change the way NVDA development happens in the future.
One other advantage of the server running Ubuntu is that I'm able to run Orca (a Gnome X-Windows screen reader for Linux / Solaris). Both the Orca and NVDA projects do have many things in common (as they are both free and open-source screen readers), and even though they are written for two entirely different operating systems, there should be much the projects can learn from each other, both in coding and user experience. I recently tested Orca with Firefox 3, and it is very clear that orca's web support is coming in leaps and bounds.
Other than server stuff, I of course have been working on the new virtual buffer library for NVDA. Work is slow but I'm definitely getting there. Design decisions need to be made very carefully as we need to make sure the code is as efficient as possible, but also make sure it will be compatible with lots of different web content.


rss
NVDA is developed by