wbuild(1)

NAME

wbuild - build X Window System widgets from compact descriptions

SYNOPSIS

wbuild [-h dir] [-p prefix] [-c dir] [-d dir] [-i file] [-s] [-n] [-l] [file,...]

DESCRIPTION

Wbuild is a program that helps in writing widgets for the X Window System Toolkit. It lets you concentrate on the parts that are unique to a widget class, because it automatically adds all the code that can be inferred from that. Here is a list of its features:

It makes writing widgets truly object-oriented, since it completely hides the implementation details, like nested structs and typecasts and details of inheritance.

It introduces the concept of "self", to allow methods and other routines to refer to the widget itself more easily.

It recognizes inherited methods and fills in the parameter list and return type automatically.

It makes defining and using new methods as easy as defining and using local functions, opening many more possibilities for inheritance.

It generates all headerfiles automatically.

It generates documentation and manuals automatically. Moreover, the documents can be in sgml as well as in TeX. The input to Wbuild consists of one or more files containing widget class definitions, both C code and documentation. The output is a set of four files for each class: the private and public header files, the implementation file and the documentation. These files are complete and do not need any further editing. In fact, they are not meant to be read by humans.

OPTIONS

Wbuild accepts the following options:

    -h dir

    the directory where the public and private header files will be put, e.g., "-h /usr/include/X11/Xpro". The default is "./X11".

    -p prefix

    the directory prefix in #include directives. E.g., the option "-p X11/Xpro" will result in the line #include <X11/Xpro/MyClassP.h> near the top of the implementation file.

    -c dir

    the directory where the implementation file will be put. Default is the current directory.

    -d dir

    the directory where the TeX-file will be put. Default is the current directory.

    -i file

    the file with the intrinsic widget classes. Default "wbuild.cfg".

    -s

    generate sgml instead of TeX.

    -n

    generate Nroff instead of TeX. Options "-s" and "-n" are mutually exclusive. If they are both present, the last one will be taken.

    -l

    omit #line directives from the C file. The compiler's error messages will not refer to the specification file, but to the C file itself.

    -o class

    only generate the named class. This is useful in Makefiles, e.g., to re-generate only those C files that are out of date.

Input format

Every input file contains one or more classes. Each class starts with a line of the form

    @class Name (Superclass) options
E.g., @class Common (Composite). The following options are possible:

    @nodoc

    Do not generate documentation for this class.

    @nocode

    Do not generate C code for this class.

    @guard=identifier

    Put #ifndef identifier at the start of the public header file. By default, the identifier is the name of the file plus _H.

    @guardP=identifier

    Idem, but for the private header file.

    @file=identifier

    The base name of the generated C files. E.g., @class XgCommon (Composite) @file=Common will create files "Common.c", "Common.h" and "CommonP.h", instead of "XgCommon.c", etc.
Next follow at most 8 different divisions (in any order). Each starts with a keyword:

    @public

    Contains public instance variables (also known as "resources").

    @private

    Contains private instance variables.

    @classvars

    Class variables.

    @methods

    Methods, both new and redefined.

    @actions

    Action functions.

    @translations

    Default translations.

    @utilities

    Local functions, types, macros, etc.

    @exports

    Convenience functions, types, macros, etc. that will be made accessible through the public header file.
Divisions may occur more than once. The contents will be grouped together automatically. Each division contains a series of sections. There are 6 types of sections, each starting with a keyword:

    @

    This section contains text (documentation).

    @def

    Defines a macro.

    @var

    Declares a variable.

    @type

    Defines a new type.

    @proc

    Defines a function.

    @trans

    Defines a default translation.
The sections can occur in any order, but the text sections are assumed to document the code section that immediately follows it (if there is one), since the documentation file will retain the order of the sections. There are small differences between the divisions with respect to what sections are allowed in each of them.

The @public division

Only @var, @def and text (@) sections may occur in the public variables division. The @var sections allow optional parts that are not possible in other divisions. A typical public variable looks like this:

    @var type name = value

    @var Pixel foreground = XtDefaultForeground
This defines a resource "foreground" of class "Foreground", plus the symbolic constants for use in C code XtNforeground and XtCForeground. It also defines a representation type XtRPixel, if it has not been defined before. The default value of this resource will be XtDefaultForeground.

In some cases the resource name should be different from the variables's name, or the representation type is not constructed from the type name. Two optional parts allow for this:

    @var <typename> type name <resource> = value

    @var <Driver> struct drv_s * drive_name <driveName> = NULL
In this example the type is a complex type without a name, so the name "Driver" is created for it. The variable contains an underscore, which we don't want in the resource name.

Since default values for resources may be given in different types (as long as there are converters for them) or even as function calls, the third optional part introduces the representation type of the default value; e.g.,

    @var type name = <typename> value

    @var Pixel foreground = <String> "black"

    @var Dimension bwidth = <CallProc> calc_wd
Note: public variables are inherited together with their default values, but you may want to give such an inherited variable a new default value, like this:

    @var width = 100
Wbuild will know that this variable is inherited from Core and fill in the type automatically.

The @private division

Like the @public divison, the private variables division contains only text and @var and @def sections, but the @var sections are much simpler, since local variables have no resource values and cannot be initialized. A typical local variable looks like this:

    @var type name

    @var GC gc

The @classvars division

Class variables are variables that are shared among all instances of a widget and its subclasses. They must be initialized. In the @classvars division only text, @var and @def sections can occur. Here is an example:

    @var int num_instances = 0
Subclasses may want to set the initial values of inherited class variables differently. The following example sets a variable that is inherited from the Core class.

    @var compress_motion = False

The @methods division

The @methods division may contain text, @def and @proc sections. New methods can be defined here and inherited ones can be redefined. If you redefine an inherited method, omit its return type and parameter list, since Wbuild will supply them automatically.

New methods must give their parameter list in ANSI style, except when there are no parameters. In that case omit the parameter list completely or write just a pair of parenteheses ().

To obviate the need for typecasts and knowledge of the various structs, Wbuild allows the symbol "$" (read "self") to occur in functions. See below.

A new method might look like this:

@proc create_gc($)
  {
    XGCValues values;
    values.background = $background;
    $gc = XtGetGC($, GCBackground, &values);
  }

(The default return type void may be omitted.) An inherited function looks like this:

@proc set_values
  {
    if ($background != $old$background)
      $create_gc($);
    return False;
  }

A macro definition looks like this:

    @def MAXSIZE = 25
(Don't forget the = sign!) There is no need to keep macros all on one line, as the next example shows:

@def done(t) =
  if (t < 10)
    return 100 + t;
  else
    return t;

The @actions division

Only text, @def and @proc sections appear in the @actions division, moreover, all functions are assumed to be actions, with parameter list ($, XEvent *event, String *params, Cardinal *num_params). The parameter list may not be redefined. Here is an action definition:

@proc DrawCell
  {
    $DrawPixmaps($, $gc, DRAW, event);
  }

The @translations division

The translations division contains only text and @trans sections. A @trans section follows the normal syntax for translations, except that arguments to action functions should be quoted:

    @trans <BtnDown>,<Btn1Up>: confirm()" @trans <LeaveWindow>: popdownSubmenu("subbox")
Unfortunately, the current implementation of Wbuild doesn't allow translations to be inherited.

The @utilities division

The @utilities division contains text, local functions (@proc), types (@type), macros (@def) and variables (@var). The only type of section not available here is the @trans section. The format of a @type section is as follows:

    @type Info = struct {int n; char *s;}" @type Link = Info *
It is equivalent to these typedefs: typedef struct {...} Info and typedef Info *Link. Variables in this division may be initialised, but need not be:

    @var int temp" @var char name[] = "Util"
You should consider using class variables instead of utility variables, because class variables are inherited an can thus be used by subclasses. In all other respects, utility variables and class variables act the same.

The @exports section

Variables, functions, types and macros that should be known outside the widget class and its subclasses, should be placed in the exprots division. Everything defined here will be declared in the public header file. You can put so-called convenience functions here. Variables may be initialized.

Note that public variables are accessible via resources, which are also put in the header file. If one of those resources uses a new type, that type has to be defined in the exports division.

The use of "self" ($) and "super" (#)

Wbuild allows the various structs that are used to implement the widget and the class to be completely hidden. The way to refer to instance variables, class variables and methods is to prefix them with a $; thus $background refers to the public variable background that is inherited from Core, $set_values refers to the method set_values, etc. A $ by itself is replaced by self (or Widget self if it appears in a parameter list).

Most methods have a parameter self, some also have other parameters of type Widget. The set_values method, for example, has the following declaration:

    @proc Boolean set_values(Widget old, Widget request, $, Arglist args, Cardinal *num_args)
Within the method, you can refer to variables in these other widgets as in the following example:

    if ($background != $old$background)
Sometimes, you may want to use a method from the superclass. Use a # instead of a $, as in the next piece of code, which is rewritten from page 207 of "X Toolkit Intrinsics Programming Manual, Motif Edition"):

@proc realize
  {
    /* This is already set, but just for example */
    *valueMask |= CWBitGravity;
    attributes->bit_gravity = NorthWestGravity;
    /* Use realize method from superclass */
    #realize($, valueMask, attributes);
  }

Automatic inheritance

A widget class that defines new methods should allow subclasses to inherit them. The normal way is to define some symbolic constants and write a method to replace the symbolic constants with real functions. Wbuild does this automatically, so that all methods are always properly inherited.

However, since wbuild uses the class_part_initialize method for this, inheritance fails if you write a new class_part_initialize method. In that case you are responsible for implementating inheritance yourself. The easiest way out is to add a call _resolve_inheritance(class) to the class_part_initialize method. This calls a function that wbuild has generated.

Example

Here is an example of a complete input for wbuild:

@class XfwfButton(XfwfLabel)  @file=Button
@ The |XfwfButton| widget is a simple button with a
single callback |activate_callback|. Except for that
callback, all resources are inherited from the
|XfwfLabel| widget. Subclasses provide buttons of
other, more specialized types.  |XfwfButton| inherits
its 3D frame from |XfwfFrame|, the location
specification resources from |XfwfBoard| and the
multi-line label from |XfwfLabel|.
The implementation is also very simple, since nearly
all code is inherited from |XfwfLabel|. There are no
new or redefined methods. In fact, just six lines of
actual code suffice to implement the widget: Object
Oriented Programming at its best!
@public
@ The |activate| is invoked from the |activate|
action, which is normally bound to a mouse click. The
|call_data| argument of the callbacks routines is
filled with a pointer to the event that triggered the
action.
@var <Callback> XtCallbackList activate = NULL
@ The default |frameWidth| is set to 2 pixels.
@var Dimension frameWidth = 2;
@ In contrast to its superclass XfwfLabel, a button
usually takes part in keyboard traversal.
@var traversalOn = True
@translations
@ By default, the |activate| action is bound to a
mouse click and to the Enter key.
@trans <Btn1Down>,<Btn1Up>: activate()
@trans <Key>Return: activate()
@actions
@ The |activate| action just calls the |activate|
callback functions, passing the |XEvent| pointer in
the |call_data| argument.
@proc activate
{
    XtCallCallbackList($, $activate, event);
}

DIAGNOSTICS

Should be self-explanatory.

BUGS

Wbuild does not handle constraint widgets. The Constraint class uses variable and method names that are the same as some in the Core class, thereby making the Core class variables inaccessible to Wbuild. To fix this, a new Constraint class has to be written, with different variable names.

Wbuild is really just the first step in a project called "Tovenaar" that will eventually include a graphic browser and editor.

FILES

Wbuild expects the following file to be present:

    wbuild.cfg

    Specifications for intrinsic classes.

SEE ALSO

Adian Nye and Tim O'Reilly, X Toolkit Intrinsics Programming Manual, O'Reilly & Associates, Inc., Sebastopol, CA, 1990.