| Getting Started | Documentation | Glish | Learn More | Programming | Contact Us |
| Version 1.9 Build 803 |
|
Adding new proxy agents to the GlishTk interface is a fiddly procedure. Aside from making decisions about whether the new agent maps exactly to an existing Display Library class, or instead makes use of multiple classes, there is a moderate amount of coding to be done. Design decisions aside, let us concentrate on the GTkColormap class, which contains a Display Library Colormap object. This class is an implementation of a GTkDisplayProxy, and makes use of some services from the DisplayOptions class. A cursory examination of GTkColormap.h will reveal that this class mostly provides a brief interface to access the facilities of the Colormap class, eg. char *GTkColormap::setoptions(Value *); is provided to allow a number of settings to be made from Glish. In the way of private data, GTkColormap simply stores a pointer to a Colormap.
Turning now to the implementation file, GTkColormap.cc, most of the interface work is done in the constructor. Each proxy agent must have a unique agent_ID, and this tag can be used by other agents to check that a provided agent for some operation is of the correct type, before casting. The contained Colormap is constructed, and then a couple of widget commands are installed. Just follow the existing code, which simply sets up a small map of Strings to functions (actually offsets into the class object). At the end of the constructor it is very important to mark the agent as valid, so that destruction can be handled properly.
The next function is a global C-style function, GTkColormap_Create. This is actually the function which is registered with Tcl to create colormap proxy agents, and after parsing the arguments (Value *args), explicitly constructs a GTkColormap object. Many things can go wrong here, so a fair component of the code is actually error checking code. This global function is actually registered to create colormap proxy agents by code in the Gdisplay_Init function implemented in gDisplay.cc. Destruction of the GTkColormap agent is straightforward. There follows a simple implementation of the required IsValid function, whose return value is examined when the destructor of the base class is called.
Finally, in GTkColormap.cc, implementations of the widget commands themselves (in this case setoptions and getoptions are given. Most of their work is involved in turning arguments coming in to the function in the Value *args style into useable data for native Display Library class functions.
Let's now look at the gDisplay.h and gDisplay.cc files. To ``export'' the GTkColormap class to Glish, it is necessary to add protected data to the TkDisplayProc class which can store the offset of a widget command in the GTkColormap class, and provide a constructor which can set up this protected data member when necessary. In gDisplay.cc the operator()(...) must be extended to handle the case where the stored offset is one into a GTkColormap, and call the method at the stored offset. Additionally, the global functionGTkColormap_Create must be declared in this file, and then registered with a call to GlishTk_Register in the implementation of Gdisplay_Init.
It is worth pointing out that the function Gdisplay_Init also does a very important thing regarding PGPLOT. It initialises the global pointer display_library_pgplot_driver to point to the global external function wcdriv_, in order that PGPLOT be able to draw on Display Library WorldCanvases. Gdisplay_Init is called when the Display Library module gDisplay.so is loaded, and so if the Display Library is not loaded, the global pointer display_library_pgplot_driver remains zero, and is (correctly) never available for use.
The last link in the chain to get colormap agents working from Glish is to add appropriate code to the Glish script gdisplay.g. This script actually provides the mechanism from Glish for loading the gDisplay.so module, and thereby installs global symbols in Glish for constructing the various proxy agents. Simply follow the existing code to add a new agent.