[ Previous | Next | Contents | Glossary | Home | Search ]
Motif 2.1 Widget Writer's Guide



The Widget Public Header File

The purpose of the widget public header file is to define the Application Programming Interface (API) for the widget. That is, the widget public header file defines the mechanism to instantiate a widget and the methods to access or modify the widget's public data.

All Intrinsics-based widgets provide a widget public header file. Motif adds few recommendations for widget public header files beyond those imposed by the Intrinsics. The purpose of this section is to review the important features of Intrinsics-based public header files and fill in the details relevant to Motif. Follow these steps to create a widget public header file:

  1. Ensure that the file is included only once.

  2. Include the appropriate header files.

  3. Allow for use by a C++ application. (This is an optional step, but is recommended.)

  4. Specify the names for the widget class and instance types.

  5. Define the string equivalents of any new resource names used by this widget.

  6. Define the application programmer's interface to the widget, including any possible convenience functions for this widget.

    The following subsections detail these steps by examining the public header file for the ExmSimple widget. This file is stored online in the demos/widgets/Exm/lib directory at pathname Simple.h.

  7. Step 1: Ensure That the File Is Included Only Once

    You must encase the contents of the header file inside a conditional compilation directive like the following:

    #ifndef _ExmSimple_h
    #define _ExmSimple_h
      ...
    #endif /* _ExmSimple_h */

    These lines prevent compiler errors by ensuring that the code inside the file will be included only once per compilation.

    Step 2: Include the Appropriate Header Files

    You must include the public header file for your widget's superclass. The superclass of ExmSimple widget is XmPrimitive. The public header file of the XmPrimitive widget is Xm/Primitive.h. Therefore, Simple.h includes the following declaration:

    #include <Xm/Primitive.h>

    Now consider the ExmString demonstration widget. The superclass of theExmString widget is ExmSimple widget. Therefore, the ExmString public header file must include the following declaration:

    #include <Exm/Simple.h>

    Step 3: Allow for C++ Compilation

    You should encase the remainder of the public header file inside the following pair of conditional compilation directives:

    #ifdef __cplusplus
    extern "C" {
    #endif
     ...
     
    #ifdef __cplusplus
    }  /* Close scope of 'extern "C"' declaration which encloses file. */
    #endif

    The preceding code prevents link-time errors when C++ applications use this widget.

    When thinking up variable names, try to avoid names that are C++ keywords, such as class and

    new. Using such keywords as variable names could prevent C++ compilation.

    Step 4: Specify Widget Class Names

    You must create externally accessible names for the widget and widget class.

    For example, the following provides the definition of widget and widget class for the ExmSimple widget:

    externalref WidgetClass exmSimpleWidgetClass;
    typedef struct _ExmSimpleClassRec *ExmSimpleWidgetClass;
    typedef struct _ExmSimpleRec     
    *ExmSimpleWidget;

    The externalref macro encapsulates all system dependencies regarding external data references. Therefore, for portability, you should use the externalref macro instead of the extern keyword in order to make variables externally accessible. You should use extern to make functions externally accessible.

    Step 5: Define String Equivalents of New Resource Names

    You must define string equivalents for every new resource name created by your widget. However, if your widget is using a resource name already used in the Motif toolkit, you should not define a string equivalent for it. You define the string equivalents with the #define preprocessor directive.

    For example, the ExmSimple widget defines a new resource named ExmNsimpleShape. Since this resource name is not defined in the standard Motif widget set, the widget public header file defines the following two string equivalents:

    #define ExmNsimpleShape "simpleShape"
    #define ExmCSimpleShape "SimpleShape"

    The preceding definitions associate a literal string with the new resource name.

    In addition to ExmNsimpleShape, the ExmSimple widget specifies two other resources: XmNmarginHeight and XmNmarginWidth. However, the widget public header file does not need to define string equivalents for these resources because these resource names are already used in the standard Motif widget set (for example, by XmLabel ). If you want to determine whether a particular resource name has already been defined by Motif, look in the Xm/XmStrDefs.h file.

    You must also define a string equivalent for each new representation type used by your widget. (See Chapter 6 for details on representation types.) For example, the ExmSimple widget creates a representation type named ExmRSimpleShape. Therefore, the widget public header file for ExmSimple defines this string equivalent as follows:

    #define ExmRSimpleShape "ExmSimpleShape"

    In addition, since the ExmRSimpleShape representation type is an enumerated data type, the widget public header file must also specify all its enumerated constants as follows:

    enum { ExmSHAPE_OVAL=0, ExmSHAPE_RECTANGLE=1 };

    You should use Motif's representation type facility to register new enumerated types. (See Chapter 6 for details.)

    Step 6: Specify the API for This Widget

    Your widget public header file should define the API for the widget. For example, the following code establishes the API for the ExmSimple widget:

    extern Widget ExmCreateSimple(
                                  Widget    parent,
                                  String    name,
                                  Arg      *arglist,
                                  Cardinal  argCount
                                 );

    If your widget contains additional convenience functions, then this is the place to declare them.


    [ Previous | Next | Contents | Glossary | Home | Search ]