## Adding Your Own WorkShop Visual Replay Commands

The command set of WorkShop Visual Replay is intended for replaying user actions and for checking the state of an application with respect to its widget hierarchy and its resource settings. You are not limited to this set of commands. You can extend it to include commands to meet your own needs, for example:

- To produce screen dumps at various points in a replay session.

- To do other sorts of consistency checking on the widget hierarchy - one example would be to interface with Doug Young's widgetlint library.

- To insert a probe or a patch for a particular debugging problem. This will be of most use in a stripped optimized binary, where you do not have access to the full power of the debugger.

### An Example

We will describe how to create a module which contains one command. This command prints a message on standard error and the name of the current shell widget. You can use this example as a template for constructing your own commands.

The source files for the command, together with a Makefile are provided in the $VISUROOT/src/examples/replay/usertemplate directory, where $VISUROOT is the location of your visu installation.

The contents of this directory are listed below:

- Makefile allows you to build the extra command module on different platforms
- README shows how to build your command module
- interface.c contains the code for the extra command described below
- xds* support files

The support files provide the framework which allows your extra commands to communicate with the WorkShop Visual Replay engine. You only need to change the xdsResources.h file - the remaining files prefixed with xds should not be altered in any way.

The contents of the interface.c file are shown below:

    #include "stdio.h"
    #include "X11/Xos.h"
    #include "X11/Xlib.h"
    #include "X11/Intrinsic.h"

    void
    exampleHalloWorld( shell, message)
    	Widget shell;
    	char * message;
    {
    	if (!message)
    		message = "no message";
    	(void) fprintf ( stderr, "Widget %s says '%s'\n",XtName(shell), message);

}

As you can see, a user-defined function should have two arguments:

- shell - is the current shell widget (passed in by WorkShop Visual Replay)

- message - a string

The message is all the text which follows the user command syntax on that line in the script. The example script fragment below shows how a command would be accessed and used:

    import usertemplate
    in ApplicationShell
    	user HalloWorld I'm here

Here the message is "I'm here".

### The Interface

The interface between all objects and the WorkShop Visual Replay engine takes place using the standard Xt resource handling routines.

Note - If you would like more information on resource structures, you are advised to consult Chapter 10 in Volume Four of the "X Toolkit Intrinsics Programming Manual" published by O'Reilly and Associates, or any other comparable book.

An entry for the new command is added to the resource list in xdsResources.h, as shown below:

    {
    	"HalloWorld", XtCCallback, XtRPointer, sizeof(XtPointer),
    	XtOffsetOf(data_t,HalloWorld), XtRImmediate,
    	(XtPointer)exampleHalloWorld

}

Only three items are of significance within this code:

- `"HalloWorld"` is the resource name

- `XtOffsetOf(data_t, HalloWorld)` gives the offset to the relevant entry in the data structure

- `(XtPointer)exampleHalloWorld` is a pointer to the address of the function

A pointer to that resource is added to the data structure within this file:

    typedef struct {

      int       type;
      XtPointer setValues;
      XtPointer getValues;
      XtPointer engineSetValues;
      XtPointer engineGetValues;
      /*-----------------------*/
      XtPointer HalloWorld;

} data_t;

Entries above the line in the data structure are common to all WorkShop Visual Replay objects.

The last thing to do in this file is to declare the function:

    extern void exampleHalloWorld();

### Building the Module

You only need to change the OBJECT line in the Makefile in order to build the module. For this example, we change it to:

        OBJECT=usertemplate

and then build the module by typing:

        make solaris

Finally, we copy or link the shared object we have built to the $VISUROOT/lib/xds directory:

        cp libusertemplate.so $VISUROOT/lib/xds

That is all there is to it.

## Summary

To add a new command to the WorkShop Visual Replay command set:

1. Add the associated function to the interface.c file.

2. Add an entry to the resource list in xdsResources.h.

3. Add a function pointer to the data structure in that file.

4. Add an extern declaration of the function to the same file.

5. If necessary, change the OBJECT line in the Makefile.

6. Build the module.

7. Copy or link it to the VISUROOT/lib/xds directory.

You can create as many modules as you wish and load them into a script at any time.

See also:

- Extending the WorkShop Visual Replay Widget Set
- Getting the Most from WorkShop Visual Replay