NAME
initialize − Object class method for initializing a widget or object instance structure.
Synopsis
typedef void (*XtInitProc)(Widget, Widget, ArgList, Cardinal *);
Widget request;
Widget init;
ArgList args;
Cardinal *num_args;
Inputs
requestSpecifies the widget or object instance with resource values set as requested by the argument list, the resource database, and the widget defaults.
initSpecifies the same widget or object with values, both resource and nonresource, as modified by superclass initialize() methods.
argsSpecifies the argument list that was passed to XtCreateWidget().
num_argsSpecifies the number of entries in the argument list.
Description
The initialize() method is registered on the initialize() field of the Object, RectObj, or Core class part structure, and is called by XtCreateWidget() to initialize the instance structure of a newly created widget. The init argument widget becomes the actual widget instance record once all initialize procedures are called; the request argument is simply a copy made after resources are fetched for the widget, but before any of the initialize() methods are called. Therefore, the initialize() method should change only the init widget, and if the method needs to call any routines that operate on a widget, it should specify init as the widget instance. The request argument is provided so that an initialize() method can distinguish initialization done by a superclass from resource values requested by a user. In some cases, this may require the method to examine args, the actual argument list passed to XtCreateWidget(). See the "Background" section below for more details. The args argument allows a widget to initialize the values of subpart resources (by calling XtSetSubvalues()) or any other resources that do not appear on the widget class resource list. A widget that automatically creates child widgets may use args and num_args in a call to XtCreateWidget(). At a minimum, the initialize() method must compute values for Core width and height, if they have not been computed by a superclass. Note that a widget may only directly assign its own width and height within the initialize(), initialize_hook(), set_values(), and set_values_hook() methods. The args and num_args arguments were added to this method in Release 4. Prior to Release 4, any initialization that requires these arguments must be done in the initialize_hook() method. The initialize() method is chained in superclass-to-subclass order and it cannot be inherited. If a widget class does not need to perform any initialization, it should specify NULL for the initialize() field of the class record. See XtCreateWidget(1) for full details on the initialization process for a newly created widget.
Usage
The initialize() method usually does the following:
•Allocates space for and copies any resources that are referenced by address. For example, if a widget has a resource that is a String, it cannot depend on the characters at that address remaining constant but must dynamically allocate space for the string and copy it to the new space. (Note though, that you should neither allocate space for nor copy callback lists; the Intrinsics handles these specially.)
•Computes values for resources that were unspecified. Most resources will have a useful default value, but others will require special handling if they are unspecified. For example, if width and height are zero, the widget might compute an appropriate width and height based on its resources, num_rows and num_columns. A label widget, as another example, might use its resource name if its label string resource is unspecified, and use the width and height of the string if its width and height fields are left unspecified.
•Computes values for fields that are derived from resources. For example, graphics contexts (GCs) that the widget uses are derived from resources such as background, foreground, and font.
•Checks certain fields for internal consistency. For example, it makes no sense to specify a colormap and a visual together when the colormap was not created with the given visual. A widget may also check some resources for reasonable values: a label widget that only supports single line labels might issue a warning message if given a string to display that contains newline characters.
•Overrides superclass resource default values or values initialized by a superclass. In particular, the size calculations of a superclass are often incorrect for a subclass, and the subclass must modify or recalculate fields declared and computed by its superclass. Note that if the programmer explicitly requested a value for a superclass resource, a subclass shouldn’t override that value. The request argument can be used to determine whether a value was explicitly requested or simply initialized by the superclass. If a class wants to override the default value of a superclass resource, it may need to check args to determine whether the resource was unspecified, or explicitly specified to be the same as the default. See the "Background" section below for more information.
•Uses args and num_args to initialize the values of any resources that do not appear on the class resource list. These may be subpart resources initialized with XtSetSubvalues(), or resources of objects or widgets that are explicitly created by the initialize() procedure.
Example
The following procedure is the initialize() method, slightly modified from the Xaw Label widget. Note that it makes a copy of its String resource, calls procedures to allocate GCs, and sets its initial size if that size is not explicitly set. An initialize() method will often call other functions to allocate GCs and other resources, so that these functions can be reused in the set_values() method. If the foreground color was changed in set_values(), for example, the GC would have to be freed and reallocated. This procedure explicitly invokes the widget’s resize() method. Label’s resize procedure will pre-compute the location at which the label will be displayed, based on the size of the window, the size of the label, and the setting of the XtNjustify resource. This must be done every time the widget changes size, and by calling the resize() method, the initialize() method avoids having to duplicate these calculations itself. Note that this procedure (and most other initialize() procedures in existence) has named its init argument new. "new" is a reserved word in C++, and your programs will be more portable if you avoid using it in your C code.
/* ARGSUSED */
static void Initialize(request, new, args, num_args)
Widget request, new;
ArgList args;
Cardinal *num_args;
{
LabelWidget lw = (LabelWidget) new;
if (lw->label.label == NULL)
lw->label.label = XtNewString(lw->core.name);
else {
lw->label.label = XtNewString(lw->label.label);
}
GetnormalGC(lw);
GetgrayGC(lw);
SetTextWidthAndHeight(lw);
if (lw->core.height == 0)
lw->core.height = lw->label.label_height + 2*lw->label.internal_height;
set_bitmap_info (lw); /* need core.height */
if (lw->core.width == 0) /* need label.lbm_width */
lw->core.width = (lw->label.label_width + 2 * lw->label.internal_width
+ LEFT_OFFSET(lw));
lw->label.label_x = lw->label.label_y = 0;
(*XtClass(new)->core_class.resize) ((Widget)lw);
} /* Initialize */
Background
Sometimes a subclass may want to overwrite values filled in by its superclass. In particular, size calculations of a superclass are often incorrect for a subclass and in this case, the subclass must modify or recalculate fields declared and computed by its superclass. As an example, a subclass can visually surround its superclass display. In this case, the width and height calculated by the superclass’s initialize() method are too small and need to be incremented by the size of the surround. The subclass needs to know whether its superclass’s size was calculated by the superclass or specified explicitly. All widgets must place themselves into whatever size is explicitly given, but they should compute a reasonable size if no size is requested. The request, init, and args arguments provide the necessary information for a subclass to determine the difference between a specified resource value and a resource value computed by a superclass. The request widget is the widget as originally requested. The init widget starts with the values in the request, but it has been updated by all the superclass’s initialize() methods called so far. If a field differs in the request and init widgets, then it has been initialized or modified by a superclass. If the field in request differs from the default value of that resource, then the user of the widget requested an explicit value for that resource, and the subclass should not modify it. If the value in request is the same as the resource default, then the user did not specify a value for that widget, or specified a value that was the same as the default. The initialize() method can check args to determine if the default value was in fact explicitly requested from an argument list. There is no way to determine, however, if the default value was explicitly requested from a resource file. Probably the best approach to this problem is to specify an unreasonable default value for the resource. A default width and height of zero are a good example. Then if request shows the default value, the resource was either unspecified or the user requested an unreasonable value. In either case, the initialize() method should set it to some other value (possibly the "real," documented default value of the resource). In the case above of a subclass that wants to place some sort of border around its superclass, the subclass can see if the width and height in the request widget are zero. If so, it may add its border size to the width and height fields that the superclass set in the init widget. If not, it means that the application programmer explicitly requested a size for the widget, and it must make do with that size.
See Also
Copyright O’Reilly & Assoc. — X Toolkit Intrinsics Reference Manual © O’Reilly & Associates